openmp的性能

我正在testingopenmp性能,我发现一些奇怪的结果,这里是我的testing代码:

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时,并行区域中的testingfunction的经过时间不等于顺序区域中的testingfunction的经过时间。

我的CPU是英特尔酷睿i5-4590(4核),平台是vs2013,win8

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

这里没有什么奇怪的。 你的代码是内存绑定的 ,从length=50000到更长的数组是由于数据不再适合CPU最后一级缓存。

  • length=50000 :数据大小是4个线程×2个数组×50000个元素×每个元素8个字节= 3.05个MiB <L3高速缓存大小(对于i5-4590,6个MiB)
  • length=100000 :数据大小为6.10 MiB> L3缓存大小
  • length=150000 :数据大小为9.16 MiB> L3缓存大小

在第二种情况下,阵列只比CPU高速缓存略大,因此时间差只有一点点大于2倍。 在第三种情况下,一半的数组数据不能被装入缓存中,并且必须从主存储器流向主存储器。

当仅从主线程调用函数时,所使用的内存是并行区域中使用的内存的四分之一,并且所有三种不同长度的阵列都完全适合L3缓存。

检查我对这个问题的答案了解更多详情。