прагма «мастер» OpenMP не должна быть заключена в прагму «параллельно для» - PullRequest
6 голосов
/ 05 октября 2011

Почему компилятор intel не позволяет мне указать, что некоторые действия в блоке openmp parallel for должны выполняться только основным потоком?

И как я могу сделать то, чего я пытаюсь достичь, без такой функциональности?

Что я пытаюсь сделать, это обновить индикатор выполнения через обратный вызов в параллель для:

long num_items_computed = 0;

#pragma omp parallel for schedule (guided)
for (...a range of items...)
{
    //update item count
    #pragma omp atomic
        num_items_computed++;

    //update progress bar with number of items computed
    //master thread only due to com marshalling
    #pragma omp master
        set_progressor_callback(num_items_computed);

    //actual computation goes here
    ...blah...
}

Я хочу, чтобы только главный поток вызывал обратный вызов, потому что, если я не обеспечу это (скажем, с помощью omp critical, чтобы гарантировать, что только один поток использует обратный вызов сразу), я получаюследующее исключение времени выполнения:

The application called an interface that was marshalled for a different thread.

... отсюда и желание сохранить все обратные вызовы в главном потоке.

Заранее спасибо.

Ответы [ 2 ]

6 голосов
/ 05 октября 2011
#include <omp.h>
void f(){}
int main()
{
#pragma omp parallel for schedule (guided)
    for (int i = 0; i < 100; ++i)
    {
        #pragma omp master
        f();
    }
    return 0;
}

Ошибка компилятора C3034 Директива «master» OpenMP не может быть непосредственно вложена в директиву «параллельно для» Visual Studio 2010 OpenMP 2.0

Может быть так:

long num_items_computed = 0;

#pragma omp parallel for schedule (guided)
for (...a range of items...)
{
    //update item count
    #pragma omp atomic
        num_items_computed++;

    //update progress bar with number of items computed
    //master thread only due to com marshalling
    //#pragma omp master it is error
    //#pragma omp critical it is right
    if (omp_get_thread_num() == 0) // may be good
        set_progressor_callback(num_items_computed);

    //actual computation goes here
    ...blah...
}
3 голосов
/ 13 марта 2013

Причина, по которой вы получаете ошибку, заключается в том, что главный поток не существует в большинстве случаев, когда код достигает строки #pragma omp master.Например, давайте возьмем код от Артема:

#include <omp.h>
void f(){}
int main()
{
#pragma omp parallel for schedule (guided)
    for (int i = 0; i < 100; ++i)
    { 
        #pragma omp master
            f();
    }
    return 0;
}

Если код скомпилируется, может произойти следующее:

Допустим, поток 0 запускается (основной поток).Он достигает прагмы, которая практически гласит: «Учитель, сделай следующий кусок кода».Будучи хозяином, можно запустить функцию.Однако что происходит, когда поток 1, 2 или 3 и т. Д. Достигает этого куска кода?

Основная директива сообщает команде present / listening , что главный поток должен выполнить f().Но команда - это одна нить, а мастера нет.Программа не будет знать, что делать после этого.

И именно поэтому, я думаю, мастеру не разрешено находиться внутри цикла for.

Замена master directive на if (omp_get_thread_num() == 0) работает, потому что теперь программа говорит: «Если вы мастер, сделайте это. В противном случае игнорируйте».

...