需要帮助弄清楚我需要更改哪些内容以实施所需的更改

问题描述

我尝试了一些方法,但无法奏效,接下来是规范,谢谢

使用 fork 和 waitpid 函数,实现该程序的新版本,其中 remover_ruido 执行的处理分为 16 个进程。

我的第一种方法是使用这个:

  const int NPROCESSES = 16;   
  pid_t pids[128];

  for (int i = 0; i < NPROCESSES;i ++) {
     pids[i] = fork();
     if (!pids[i]) {  
       remover_ruido(amostras_out,amostras_in,n_amost);
       exit(0);
  }
}

 for (int i = 0; i < NPROCESSES; i++)
      waitpid(pids[i],0);

我做了一个类似的项目,但使用线程,要求将进程划分为 50 个线程。不知道能不能用同样的方法


#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <string.h>
#include <math.h>

#define NMIN 4000

double mytime();
void *malloc_pshared(size_t size);      // aloca memória partilhada entre processos
void remover_ruido(short *dados_out,short *dados_in,int nelem);

int main(int argc,char *argv[])
{
    int n_amost;

    if (argc != 2 || (n_amost = atoi(argv[1])) < NMIN) {
        printf("Sintaxe: \"%s N\",com N não inferior a %d\n",argv[0],NMIN);
        exit(1);
    }

    short *amostras_in = (short *) malloc_pshared(sizeof(short) * n_amost);

    if (amostras_in == NULL) {
        exit(1);
    }
    else {
        for (int i = 0; i < n_amost; ++i)
            amostras_in[i] = i * 1.0;
    }

    short *amostras_out = (short *) malloc_pshared(sizeof(short) * n_amost);

    if (amostras_out == NULL)
        exit(1);

    double t0 = mytime();

    remover_ruido(amostras_out,n_amost);

    printf("Tempo de execução: %f (s)\n",mytime() - t0);

    return 0;
}

double mytime() {
   struct timeval tp;
   struct timezone tzp;

   gettimeofday(&tp,&tzp);
   return ( (double) tp.tv_sec + (double) tp.tv_usec * 1.e-6 );
}

 void *malloc_pshared(size_t size){
      return mmap(NULL,size,PROT_READ | PROT_WRITE,MAP_SHARED| MAP_ANONYMOUS,-1,0);
}

void remover_ruido(short *dados_out,int nelem)
{
    // não implementada
    for (int i = 0; i != nelem; ++i)
        dados_out[i] = sqrt(dados_in[i] * dados_in[i]);
}

解决方法

这里有一个轻微的重构,用于在每个进程的基础上拆分数据。我编码了它,但没有编译或测试它:

const int NPROCESSES = 16;
pid_t pids[128];

int chunksize = n_amost / NPROCESSES;       // number of elements per process
int remain = n_amost;                       // number of elements remaining
int curoff;                                 // current offset into arrays
int cursize;                                // current length for process

for (int i = 0; i < NPROCESSES; i++,remain -= cursize) {
    pids[i] = fork();
    if (! pids[i]) {
        // get index into arrays for this process
        curoff = i * chunksize;

        // assume we're a middle process -- use the calculated length
        cursize = chunksize;

        // last process must get the remainder of the array
        if (i >= (NPROCESSES - 1))
            cursize = remain;

        remover_ruido(&amostras_out[curoff],&amostras_in[curoff],cursize);
        exit(0);
    }
}

for (int i = 0; i < NPROCESSES; i++)
    waitpid(pids[i],0);

请注意,还有其他方法可以拆分偏移量/长度,但这应该会让您开始

请注意,您应该仔细检查您的 mmap 调用以确保它符合您的要求。

,

此变体与 Craig Estey 的变体非常相似,不同之处在于它实际上有效,因为它不会修改子代中的变量,前提是它会在父代中被修改。 ;-)

只有您第一个方法的路线

       remover_ruido(amostras_out,amostras_in,n_amost);

需要改成

       int from = n_amost*i/NPROCESSES,to = n_amost*(i+1)/NPROCESSES;
       remover_ruido(amostras_out+from,amostras_in+from,to-from);