在 C 语言中运行并发进程并测量运行时间

Running concurrent process in C and measure running time

提问人:Nicolás Montañez Velasco 提问时间:10/29/2023 更新时间:10/29/2023 访问量:40

问:

我正在用 C 语言创建一个程序,该程序从文件中加载矩阵,将其分成 N 段以提供给 N 个进程。

每个进程都应计算矩阵该段中的每 0 个元素。

我应该测量完成整个程序所需的时间。因此,从理论上讲,如果我添加更多进程,它应该花费更少的时间,以成反比的意义。

为此,我测量了每个过程的时间,如下所示:

for (int i = 0; i < num_processes; ++i)
  {
    pid_t pid = fork();

    if (pid == -1)
    {
      perror("Fork failed");
      exit(EXIT_FAILURE);
    }

    if (pid == 0)
    {
      // Child process

      // Calculate the start and end rows for this process
      int start_row = i * segment_rows + (i < remaining_rows ? i : remaining_rows);
      int end_row = start_row + segment_rows + (i < remaining_rows ? 1 : 0);

      // Perform counting in the segment
      start = clock();
      long count = countZeros(matrix + start_row * columns, end_row - start_row, columns);
      end = clock();

      // Print the count and time taken by this process
      printf("Process %d Count: %ld Time: %f seconds\n", i, count, ((double)(end - start)) / CLOCKS_PER_SEC);

      exit(EXIT_SUCCESS);
    }
  }

例如,当我使用 1000 x 2000 矩阵运行它时,如果我继续添加进程,每个进程的时间确实会减少(我设置的限制是可用的 CPU 内核数量)。

问题是,当我像这样测量整个程序时间时:

// Wait for all child processes to finish
  start = clock();
  for (int i = 0; i < num_processes; ++i)
  {
    wait(NULL);
  }
  end = clock();
// Print the total time taken by all processes
  printf("Total time: %f seconds\n", ((double)(end - start)) / CLOCKS_PER_SEC);

现在的时间不仅增加了,而且甚至与所有进程的时间无关。

所以最后一个问题是,应该用其他方式来衡量总时间,还是这个问题与程序中完成的并发管理有关?

以下是一些显示所描述问题的屏幕截图:

enter image description here

下面是包含完整代码的 repo:https://github.com/NicolasMonta1807/matrix-concurrency

如果您对更多感兴趣,这应该应用于此处构建的稀疏矩阵验证器: https://github.com/NicolasMonta1807/sparse-matrix-validator .总的来说,它是有效的,它完成了它的工作,但唯一的问题是这篇文章中所说的。

C 并发 进程 稀疏矩阵

评论

0赞 Weather Vane 10/29/2023
clock()实际上并不是衡量短执行时间的最佳工具:更适合至少需要 1 秒的进程。
0赞 Nicolás Montañez Velasco 10/29/2023
您是否碰巧知道是否有其他方法可以在 C 中测量短时间?我试着用时间做,但它不以毫秒为单位计算
1赞 Weather Vane 10/29/2023
请看 在C语言中计算程序的执行时间

答:

0赞 Nicolás Montañez Velasco 10/29/2023 #1

所以,最后是使用 .正如 Weather Vane 在他们的评论中建议的那样,我将其替换为 ,并且它按预期工作。clock()clock_gettime()

/**
     * ---------- TIMER ----------
     */
    struct timespec begin, end;
    clock_gettime(CLOCK_REALTIME, &begin);

    int total = 0;

    for (int i = 0; i < num_processes; ++i)
    {
      wait(NULL);
    }

    clock_gettime(CLOCK_REALTIME, &end);
    double time_spent = (end.tv_sec - begin.tv_sec) +
                        (end.tv_nsec - begin.tv_nsec) / BILLION;
    printf("Terminado en %f\n", total, time_spent);

我真的很感谢你的帮助。