我很想知道在具有大量内核的多核处理器上使用OpenMP的含义,特别是在MAESTRO板上。 MAESTRO板有49个处理器,以7x7配置排列成二维阵列。每个核心都有自己的L1和L2缓存。在这里可以看到电路板的布局:http://i.imgur.com/naCWTuK.png
我一直试图运行一些使用OpenMP的矩阵乘法代码,而加速的性质并不是我的预期。在普通计算机上运行此代码,比如我的笔记本电脑,我注意到随着我增加使用的线程数量,我会减少执行时间。正如我所料,运行OpenMP代码会带来巨大的性能提升。
但是,在MAESTRO上运行相同的代码不会产生相同的结果。使用OpenMP似乎使它运行得更慢,我只能在使用正在使用的阵列的缓存一致性设置并尝试使用OpenMP提供的不同调度技术后获得性能提升。即便如此,加速也很小。在我看到性能下降之前,我只能将线程数增加到某一点,如果我使数组太大,OpenMP代码运行速度比串行代码慢。
在网上看之后,我看到一些论文讨论“OpenMP中的Tile Aware Parallelization”,并说OpenMP是“瓦片遗忘”(http://www.capsl.udel.edu/pub/doc/papers/Gan-IWOMP2009.pdf)。我不确定这是多么相关,但我唯一能够讨论在具有大量内核的基于磁贴的处理器上使用OpenMP的问题。
所以我想我的主要问题是:从普通台式电脑到基于磁贴MAESTRO的高性能多核处理器,OpenMP程序的性质如何变化?在MAESTRO上OpenMP的性能是否可以改进,或者由于处理器的类型,我会遇到上限吗?尝试在MAESTRO等处理器上使用OpenMP并行化代码时,可能导致性能下降的原因是什么?专注于其他并行化代码的方式,例如使用MPI,会更有益吗?
我在MAESTRO上运行的当前代码:
alloc_attr_t attrA = ALLOC_INIT;
alloc_attr_t attrB = ALLOC_INIT;
alloc_attr_t attrC = ALLOC_INIT;
alloc_set_home(&attrA, ALLOC_HOME_INCOHERENT);
alloc_set_home(&attrB, ALLOC_HOME_INCOHERENT);
alloc_set_home(&attrC, ALLOC_HOME_TASK);
INT32_TYPE *A=alloc_map(&attrA, sizeof(INT32_TYPE)*(size*size));
INT32_TYPE *B=alloc_map(&attrB, sizeof(INT32_TYPE)*(size*size));
INT64_TYPE *C=alloc_map(&attrC, sizeof(INT64_TYPE)*(size*size));
for(i=0;i<(size*size);i++)
{
A[i]=rand();
B[i]=rand();
C[i]=0;
}
TIME_GET(&start);
//parallelize with OpenMP
#pragma omp parallel for num_threads(threads) private(i,j,k) schedule(dynamic)
for(i=0;i<size;i++)
{
for(j=0;j<size;j++)
{
for(k=0;k<size;k++)
{
C[i*size+j]+=A[i*size+k]*B[k*size+j];
}
}
}
TIME_GET(&end);
注意:此配置已经从我测试的产品中获得了最佳性能。我尝试了不同的缓存一致性设置,不同的调度技术,不同的块大小,以及将循环折叠到不同的级别。