2011-02-04 7 views
0

У меня есть следующий код в VS2008:OpenMP для цикла игнорирует положение num_threads

int i,j; 
bool pr = false; 
#pragma omp parallel for private(pr) num_threads(2) 
for(i=0;i<PIC_X;i++) 
{ 
    int rank = omp_get_thread_num(); 
    int count = omp_get_num_threads(); 
    if (!pr) 
    { 
     printf_s("Hello from thread %d of %d\n", rank, count); 
     pr = true; 
    } 
    for(j=0;j<PIC_Y;j++) 
    { 
     // do stuff 
    } 
} 

(не пытается сделать вложенный цикл OpenMP, в случае, если вам интересно). Проблема в том, что предложение num_threads не имеет никакого эффекта: я только когда-либо получаю «Hello from thread 0 of 1» на выходе. Я также попытался использовать omp_set_num_threads(2), но безрезультатно. Что дает?

+1

Ознакомьтесь с http://software.intel.com/en-us/articles/32-openmp-traps-for-c-developers/ - Это действительно помогло мне –

ответ

4

Вы установили pr вне параллельной области, а затем сделали pr приватным, поместив его в частное предложение. Это означает, что каждый поток имеет pr, но частные переменные pr не инициализируются. Используйте firstprivate, а не private для pr, чтобы инициализировать частные переменные.

Тем не менее, вы ошибаетесь в том, что счетчики циклов являются закрытыми по умолчанию. Счетчик циклов для работы (или канонический) для (например, переменной i) является приватным (раздел 2.4.1 для конструкции спецификации OMP V2.0). Но «j» - нет. См OpenMP V2.0 спецификации (что поддерживает Microsoft в VS2008), раздел 2.7.2 Обмен данными Атрибут Морозы:

Если переменная видна, когда параллельно или работа обмен конструкт встречается, и переменная не указана в предложении атрибута разделения или директиве threadprivate , то переменная является общей. Статические переменные, объявленные в динамическом диапазоне , являются параллельными. Куча выделенной памяти (например, с использованием malloc() в C или C++ или нового оператора на C++) является общей. Однако указатель на эту память может быть как личным, так и общим.) Переменные с автоматическим хранением Длительность, заявленная в динамической протяженности параллельного региона, является частной.

Что касается omp_get_num_threads(), возвращающего 1, все, о чем я могу думать, это то, что вы не скомпилировали это с включенным флагом OpenMP.

1

Если OpenMP разбивает внешний цикл на 2 (то есть один процесс получает 0..PIC_X/2), а второй получает последнюю половину, только один процесс будет видеть i == 0.

И если ваше изображение организовано, как и все изображения, которые я видел, внешний цикл должен быть Y, а внутренний цикл должен быть X, а внутренний цикл должен быть OpenMP'ed, так как изображения обычно организованы в памяти ,

+0

+1, хотя OP отредактировал сообщение, чтобы удалить 'if (i == 0)' code xcramps изначально был правильным. –

+0

Хотя это было неловко, это не проблема: вопрос был отредактирован с помощью (надеюсь) правильного решения только для печати один раз за цикл, и я до сих пор получаю только «Hello from thread 0». Кроме того, 'get_num_threads()' также постоянно дает 1. – suszterpatt

+0

Невозможно, чтобы вы работали на машине unicore, да? Кроме того, вам нужно сделать i и j частным. – xcramps