c - 面向初学者的 OpenMP

标签 c multithreading parallel-processing openmp

我刚开始使用 openMP;我写了一些 C 代码以检查我所学的内容是否正确。但是我发现了一些麻烦;这是main.c代码

#include "stdio.h"
#include "stdlib.h"
#include "omp.h"
#include "time.h"

int main(){

float msec_kernel;
const int N = 1000000;
int i, a[N];

clock_t start = clock(), diff;
#pragma omp parallel for private(i)
for (i = 1; i <= N; i++){
    a[i] = 2 * i;
}
diff = clock() - start;
msec_kernel = diff * 1000 / CLOCKS_PER_SEC; 
printf("Kernel Time: %e s\n",msec_kernel*1e-03);
printf("a[N] = %d\n",a[N]);
return 0;
}

我的目标是看看使用 1 个和 2 个 CPU 的 PC 执行这样的操作需要多长时间;为了编译程序,我在终端中输入以下行:

gcc -fopenmp main.c -o main

然后我像这样选择 CPU 的数量:

export OMP_NUM_THREADS=N

其中 N 为 1 或 2;但是我没有得到正确的执行时间;我的结果实际上是:

Kernel Time: 5.000000e-03 s
a[N] = 2000000

Kernel Time: 6.000000e-03 s
a[N] = 2000000

都对应N=1和N=2。正如您所看到的,当我使用 2 个 CPU 时,它比只使用一个 CPU 花费的时间稍微多一点!我究竟做错了什么?我该如何解决这个问题?

最佳答案

首先,使用多核并不意味着您将获得更好的性能。

OpenMP 必须管理核心之间的数据分布,这也需要时间。特别是对于非常基本的操作,例如您只执行一次乘法,顺序(单核)程序的性能会更好。

其次,通过只遍历数组的每个元素一次而不执行任何其他操作,您不会使用缓存内存,而且肯定不会使用 cpu 之间的共享缓存。

所以你应该开始阅读一些关于一般算法性能的东西。在我看来,使用共享缓存来利用多个核心是本质。 今天的计算机已经到了 CPU 比内存分配、读取或写入快得多的阶段。这意味着当使用多核时,只有使用共享缓存之类的东西才会有好处,因为数据分布、线程初始化和管理它们也会耗费时间。真正看表演speedup (请参阅链接,并行计算中的基本术语)您应该编写一种算法,该算法重点放在计算而不是内存上;这与 locality 有关(另一个重要术语)。

因此,如果您想通过使用多核来体验巨大的性能提升,请在 10'000*10'000 等大矩阵上进行矩阵-矩阵-乘法测试。并绘制一些图,其中 inputsize(matrix-size) 到 time 和 matrix-size 到 gflops并将多核版本与顺序版本进行比较。

同时让自己熟悉复杂性分析(大 O 表示法)。 矩阵-矩阵-乘法的局域性为 O(n)。

希望这有帮助:-)

我建议直接在#pragma 行 #pragma omp parallel for num_threads(2) 或使用 omp_set_num_threads 函数 omp_set_num_threads(2 );

此外,在进行时间/性能分析时,务必多次运行程序,然后取所有运行时间的平均值或类似的东西。仅运行一次相应的程序不会为您提供有意义的已用时间读数。总是连续多次调用。不要忘记改变数据质量。

我建议编写一个 test.c 文件,它将您的实际程序函数置于一个循环中,然后计算每次执行该函数的时间:

int executiontimes = 20;
clock_t initial_time = clock();
for(int i = 0; i < executiontimes; i++){
    function_multiplication(values);    
}
clock_t final_time = clock();
clock_t passed_time = final_time - initial_time;
clock_t time_per_exec = passed_time / executiontimes;

改进此测试算法,为您的值添加一些 rand() 等。用 srand() 等为它们播种。如果您对这个主题有更多问题或对我的回答发表评论,我会尝试进一步解释添加更多解释。

关于c - 面向初学者的 OpenMP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28798142/

相关文章:

c - 我如何按照 MATLAB 语法编写此 C 代码片段?

c - 请求非结构或 union 中的成员 '_file'

c# - 如何使用命名管道与 C 和 C# 程序通信

c++ - 使用 MinGW windows 7 将静态库 .lib 转换为动态库 .dll

c++ - 在时区之间转换时间的线程安全方法

c++ - std::lock_guard() 用于锁定的 std::mutex

c - 线程创建 : error error: ‘cpu’ undeclared (first use in this function)

python - Apache Beam 管道步骤未并行运行? (Python)

matlab - 为什么 Matlab 2014a/b 中的 TreeBagger 只使用并行池中的几个 worker ?

c - 循环崩溃中的 OpenMP 错误