2013-12-26 2 views
0

кодВ VS2010 использование openMP firstprivate не удалось?

double t; 
double limit = 10; 
double result = 1000; 
int i; 

#pragma omp parallel sections default(none) firstprivate(result) lastprivate(result) private(t) shared(limit) 
{ 
    #pragma omp section 
    { 
     printf("Section1: result = %f\n", result); 
     result += 55; 
     printf("Section1: result = %f\n", result); 
    } 
    #pragma omp section 
    { 
     printf("Section2: result = %f\n", result); 
     result += 3628800; 
     printf("Section2: result = %f\n", result); 
    } 
} 
printf("result1 = %0.0lf\n", result); 

В результате

Section1: result = 1000.000000 
Section1: result = 1055.000000 
Section2: result = 1000.000000 
Section2: result = 3629800.000000 
result1 = 3629800 

ИЛИ

Section1: result = 1000.000000 
Section1: result = 1055.000000 
Section2: result = 1055.000000 
Section2: result = 3629855.000000 
result1 = 3629855 

В VS2010, я использую firstprivate для инициализации result в разделе.
Я думаю, что в section1 или разделе 2, результат должен быть 1000 перед операцией +

Однако результат может быть инициализирован в 1055 в разделе 2 при запуске программы. Может кто-нибудь сказать мне, почему?

ответ

1

В стандарте OpenMP ничего нет, что гарантирует, что разделы должны выполняться разными потоками. Рабочая среда MSVC OpenMP назначает разделы динамически, т. Е. Как только поток становится готовым, ему назначается следующий раздел в очереди. В этом случае возможно, что другие потоки все еще создаются в тот момент, когда главный поток завершил выполнение первой секции. Что произойдет, так это то, что главный поток начнет выполнение второго раздела. Именно этот сценарий показан в примере, который сопровождает описание sections в MSDN. Поскольку в каждом потоке применяются статьи (first|last)private, а не по разделу, result будет иметь начальное значение 1055.0 во втором разделе.

Вы можете легко увидеть, как это происходит:

#pragma omp section 
{ 
    printf("Section1: thread = %d\n", omp_get_thread_num()); 
    printf("Section1: result = %f\n", result); 
    result += 55; 
    printf("Section1: result = %f\n", result); 
} 
#pragma omp section 
{ 
    printf("Section2: thread = %d\n", omp_get_thread_num()); 
    printf("Section2: result = %f\n", result); 
    result += 3628800; 
    printf("Section2: result = %f\n", result); 
} 

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

Разделы OpenMP должны быть независимыми. В вашем случае существует зависимость данных между двумя разделами, переносимыми переменной result.

Смежные вопросы