gpt4 book ai didi

c - 使用 openmp 看不到任何加速

转载 作者:太空宇宙 更新时间:2023-11-04 01:57:29 25 4
gpt4 key购买 nike

我是 openmp 的新手,正在尝试了解它的结构..

这是我写的一个简单代码...(数字的平方)..

#include <omp.h>
#include <stdio.h>

#define SIZE 20000
#define NUM_THREADS 50
int main(){

int id;
int output[SIZE];
omp_set_num_threads(NUM_THREADS);
double start = omp_get_wtime();
#pragma omp parallel for
//{
//id = omp_get_thread_num();

for (int i=0; i<SIZE;i++){
id = omp_get_thread_num();
//printf("current thread :%d of %d threads\n", id, omp_get_num_threads());
output[i] = i*i;
}
//}
double end = omp_get_wtime();

printf("time elapsed: %f for %d threads\n", end-start, NUM_THREADS);
}

现在,改变线程数应该减少时间..但实际上它增加了时间?我做错了什么?

最佳答案

这很可能是由于您选择了要检查的问题。让我们看看您的并行循环:

#pragma omp parallel for
for (int i=0; i<SIZE;i++){
id = omp_get_thread_num();
output[i] = i*i;
}

您已指定 50 个线程并声明您有 16 个核心。

串行情况忽略 OMP 指令并且可以执行循环的积极优化。每个元素 i 都是 i*i,一个简单的乘法,只依赖于循环索引。 id 可以完全优化掉。这可能会完全向量化,如果您的处理器是现代的,它可能可以在一条指令 (SIMD) 中执行 4 次乘法运算,这意味着对于 size=2000,您正在查看 500 次 SIMD 乘法运算(没有数据获取开销和一个缓存友好的商店)。这将非常很快。

或者,让我们看看并行版本。您正在初始化 50 个线程——昂贵!。您正在引入许多上下文切换,因为即使您具有处理器亲和性,您也已经超额订阅了您的内核。 50 个线程中的每一个都将运行循环的 40 次迭代。如果幸运的话,编译器会稍微展开循环,这样它就可以执行 10 次 SIMD 乘法迭代。乘法,无论是否为 SIMD,仍然会很快。你最终得到的是相同数量的实际工作,所以每个处理器有 1/16 的工作,但是创建和销毁 50 个线程的开销创建的工作比并行增益更多。这是无法从并行化中获益的一个很好的例子。


您要做的第一件事是将线程数限制为实际核心数。将不必要的上下文切换添加到执行时间不会给您带来任何好处。多于内核的线程通常不会使其运行得更快。

你想做的第二件事是在你的循环中做一些更复杂的事情,并且做很多次(google for examples,有很多)。在构建工作循环时,您还需要牢记缓存性能,因为构建不当的循环不能很好地加速。

当您将工作更改为比线程开销、令人尴尬的并行和出色的缓存性能更复杂时,您可以开始看到 OpenMP 的真正优势。您要做的最后一件事是将您的循环从串行到 16 线程进行基准测试。例如:

enter image description here

关于c - 使用 openmp 看不到任何加速,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32163841/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com