我正在做一个关于使用openmp进行图像处理的项目。 我有一个简单的代码如下。 该程序使用gcc4.3.3在我的linux平台上顺利运行。 但该程序在xp平台上运行得非常慢(使用intel编译器v11的visual studio 2005)。 经过一些分析,瓶颈是kernel32.dll中的SleepEx
是我的openmp(vc 2005)比gcc4.3.3更早吗?
unsigned char **a_data,
**b_data,
**c_data,
*p,
*p_a,
*p_b,
*p_c;
unsigned long nr,
nc;
nr = nc = 64;
a_data = (unsigned char **) malloc(nr*sizeof(unsigned char *));
p = (unsigned char *) malloc(nr*nc*sizeof(unsigned char));
for(int i=0; i<nr; i++)
{
a_data[i] = p + i*nr;
}
b_data = (unsigned char **) malloc(nr*sizeof(unsigned char *));
p = (unsigned char *) malloc(nr*nc*sizeof(unsigned char));
for(int i=0; i<nr; i++)
{
b_data[i] = p + i*nr;
}
c_data = (unsigned char **) malloc(nr*sizeof(unsigned char *));
p = (unsigned char *) malloc(nr*nc*sizeof(unsigned char));
for(int i=0; i<nr; i++)
{
c_data[i] = p + i*nr;
}
for(int i=0; i<nr; i++)
{
p_a = a_data[i];
p_b = b_data[i];
p_c = c_data[i];
#pragma omp parallel for
for(int j=0; j<nc; j++)
{
p_a[j] = p_b[j] + p_c[j];
}
}
答案 0 :(得分:0)
如果我理解正确SleepEx
用于暂停线程等待某些条件 - 这表明花费在 SleepEx中的时间是线程没有做任何有用的事情的时间。这反过来表明负载平衡或争用访问共享变量的可能性很小,或者是并行化的其他后果。
在得出XP的某些“错误”(可能是正确的,但你还没说服我)之前,你应该:
a)尝试并行化外环(for(int i=0; i<nr; i++)
)而不是内环。玩循环调度。尝试将循环折叠成一个。
b)明确哪些变量是共享的,哪些变量是私有的。我写Fortran并且不记得C的默认值是什么,只是它们略有不同。您的临时变量p_a, p_b, p_c
可能会被共享,但看起来并非如此。
c)弄清楚程序的内存访问模式,确保它们充分利用缓存。