openmp генерирует большие издержки в kernel32.dll (SleepEx) - PullRequest
0 голосов
/ 17 декабря 2010

Я делаю проект по обработке изображений с использованием openmp. У меня есть простой код следующим образом. Программа работала без проблем на моей Linux-платформе с gcc4.3.3. Но программа работала невероятно медленно на платформе XP (Visual Studio 2005 с компилятором Intel v11). После некоторого анализа узким местом стало SleepEx в kernel32.dll

мой 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 голосов
/ 17 декабря 2010

Если я правильно понимаю, SleepEx используется для приостановки потока в ожидании какого-либо условия - что говорит о том, что время, потраченное в SleepEx - это время, когда поток не делает ничего полезного. Это, в свою очередь, говорит о плохой балансировке нагрузки или конкуренции за доступ к общим переменным, или о некоторых других последствиях распараллеливания.

Прежде чем прийти к выводу, что с XP что-то не так (что может быть правильным, но вы меня не убедили), вам следует:

a) Поэкспериментируйте с распараллеливанием внешнего цикла (for(int i=0; i<nr; i++)), а не внутреннего. Поиграйте с цикличным планированием. Попробуйте свернуть петли в одну.

b) Укажите, какие переменные являются общими, а какие частными. Я пишу на Фортране и не могу вспомнить, каковы настройки C по умолчанию, только то, что они немного отличаются. Ваши временные переменные p_a, p_b, p_c могут быть общими, но это не выглядит так, как будто они должны быть.

c) Определите шаблоны доступа к памяти вашей программы, убедитесь, что они эффективно используют кэш.

...