openmp在kernel32.dll(SleepEx)中产生大量开销

时间:2010-12-17 03:26:04

标签: programming-languages parallel-processing

我正在做一个关于使用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];
    }
}

1 个答案:

答案 0 :(得分:0)

如果我理解正确SleepEx用于暂停线程等待某些条件 - 这表明花费在 SleepEx中的时间是线程没有做任何有用的事情的时间。这反过来表明负载平衡或争用访问共享变量的可能性很小,或者是并行化的其他后果。

在得出XP的某些“错误”(可能是正确的,但你还没说服我)之前,你应该:

a)尝试并行化外环(for(int i=0; i<nr; i++))而不是内环。玩循环调度。尝试将循环折叠成一个。

b)明确哪些变量是共享的,哪些变量是私有的。我写Fortran并且不记得C的默认值是什么,只是它们略有不同。您的临时变量p_a, p_b, p_c可能会被共享,但看起来并非如此。

c)弄清楚程序的内存访问模式,确保它们充分利用缓存。