openmp的性能

Posted

技术标签:

【中文标题】openmp的性能【英文标题】:The performance of openmp 【发布时间】:2016-05-06 09:16:07 【问题描述】:

我正在测试,但我发现一些奇怪的结果,这是我的测试代码:

void test()

int a = 0;
clock_t t1 = clock();
int length =50000;
double *t3 = new double[length]();
double *t4 = new double[length]();
for (int i = 0; i <8000; i++)

for (int j = 0; j < length; j++)
    
        t3[j] = t3[j] + t4[j];
    

clock_t t2 = clock();
printf("Time = %d  %d\n", t2 - t1,omp_get_thread_num());
delete[] t3;
delete[] t4;


int main()

clock_t t1 = clock();
printf("In parallel region:\n");
#pragma omp parallel for
for (int j = 0; j < 8; j++)


    test(); 


clock_t t2 = clock();
printf("Total time = %d\n", t2 - t1);
printf("In sequential region:\n");
test();
printf("\n");

当我分别设置length=50000length=100000length=150000时,结果如图:

很奇怪

经过的时间不是一条直线(length=150000的经过时间几乎是length=50000的5倍),而计算量是一条直线。 同样奇怪的是,当length=150000 时,并行区域中测试函数的运行时间不等于顺序区域中测试函数的运行时间。

我的cpu是intel Core i5-4590(4核),平台是vs2013,win8

非常希望有人能告诉我原因以及如何解决这个问题以提高,非常感谢。

【问题讨论】:

@ZheyuanLi 我从书中挑选了这段代码,那么我应该使用什么计时器来获得正确的结果? @Debo 使用omp_get_wtime() 【参考方案1】:

这里没有什么奇怪的。您的代码是 memory bound,从 length=50000 到更长的数组时速度变慢是由于数据不再能够放入 CPU 的最后一级缓存。

length=50000:数据大小为 4 个线程 x 2 个数组 x 50000 个元素 x 每个元素 8 个字节 = 3.05 MiB i5-4590 为 6 MiB) length=100000:数据大小为 6.10 MiB > L3 缓存大小 length=150000:数据大小为 9.16 MiB > L3 缓存大小

在第二种情况下,数组只是略大于 CPU 缓存,因此时间差仅比 2x 大一点。在第三种情况下,一半的数组数据无法放入缓存中,必须从主内存流入和流入。

仅从主线程调用该函数时,使用的内存是并行区域中使用的内存的 1/4,并且数组完全适合所有三种不同长度的 L3 缓存。

查看我对this question 的回复了解更多详情。

【讨论】:

不是每个CPU都有自己的缓存吗? @RishitSanmukhani,i5-4590 有 6 MiB 的共享 L3 缓存,四个内核中的每一个都有 256 KiB 的私有 L2 缓存和 32 KiB 的私有 L1 缓存。

以上是关于openmp的性能的主要内容,如果未能解决你的问题,请参考以下文章

单核CPU使用openmp,会大幅度提高计算性能吗?

为啥 OpenMP 'simd' 比 'parallel for simd' 有更好的性能?

多个 OpenMP 线程读取(不写入)共享变量的性能成本?

openmp:线程数的增加会降低性能

使用 Visual Studio 2013 降低 OpenMP 的性能

在针对顺序运行进行优化的程序上使用 openMP 后没有性能提升