【发布时间】:2014-09-17 10:18:11
【问题描述】:
我正在使用 8 个 OpenMP 线程运行以下循环:
float* data;
int n;
#pragma omp parallel for schedule(dynamic, 1) default(none) shared(data, n)
for ( int i = 0; i < n; ++i )
{
DO SOMETHING WITH data[i]
}
由于 NUMA,我想用线程 0,1,2,3 运行循环的前半部分 (i = 0, ..., n/2-1) 后半部分 (i = n/2, ..., n-1),线程数为 4,5,6,7。
基本上,我想并行运行两个循环,每个循环使用一组单独的 OpenMP 线程。
如何使用 OpenMP 实现这一目标?
谢谢
PS:理想情况下,如果一组线程完成了循环的一半,而另一半循环仍未完成,我希望已完成组的线程加入未完成组处理另一半循环。
我正在考虑类似下面的事情,但我想知道我是否可以使用 OpenMP 做到这一点而无需额外的簿记:
int n;
int i0 = 0;
int i1 = n / 2;
#pragma omp parallel for schedule(dynamic, 1) default(none) shared(data,n,i0,i1)
for ( int i = 0; i < n; ++i )
{
int nt = omp_get_thread_num();
int j;
#pragma omp critical
{
if ( nt < 4 ) {
if ( i0 < n / 2 ) j = i0++; // First 4 threads process first half
else j = i1++; // of loop unless first half is finished
}
else {
if ( i1 < n ) j = i1++; // Second 4 threads process second half
else j = i0++; // of loop unless second half is finished
}
}
DO SOMETHING WITH data[j]
}
【问题讨论】:
-
你能解释一下为什么你说“由于 NUMA,我想用线程 0,1 运行循环的前半部分 (i = 0, ..., n/2-1) ,2,3 和后半部分 (i = n/2, ..., n-1),线程为 4,5,6,7。"?
-
因为
data是这样分配的,它的前半部分靠近一个套接字(我运行线程0、1、2、3的地方),而后半部分靠近另一个套接字(我在其中运行线程 4、5、6、7) -
您的操作系统、硬件和编译器是什么? Linux?两个插槽英特尔至强?海合会?
-
@Zboson RHEL 6.3,8 插槽 Xeon CPU E5-4640(总共 64 个内核)。 1 TB 内存。帖子中的示例已简化。我需要超过 2 组线程。编译器:GCC 4.8.3 或最新的 Intel。
-
您确定要
schedule(dynamic,1)还是要sechedule(static)?
标签: multithreading performance openmp affinity numa