簡體   English   中英

OpenMP和#pragma omp atomic

[英]OpenMP and #pragma omp atomic

我有OpenMP的問題。 MSVS編譯器拋出“pragma omp atomic有不正確的形式” 我不知道為什么。 代碼:(程序使用積分方法指定PI編號)

#include <stdio.h>
#include <time.h>
#include <omp.h>

long long num_steps = 1000000000;
double step;

int main(int argc, char* argv[])
{
    clock_t start, stop;
    double x, pi, sum=0.0;
    int i;
    step = 1./(double)num_steps;
    start = clock();

    #pragma omp parallel for
    for (i=0; i<num_steps; i++)
    { 
        x = (i + .5)*step;
        #pragma omp atomic //this part contains error
        sum = sum + 4.0/(1.+ x*x);  
    }

    pi = sum*step;
    stop = clock();

    // some printf to show results
return 0;
}

根據當前的OpenMP標准,您的程序是完全語法正確的OpenMP代碼(例如,它使用GCC 4.7.1編譯未修改),除了x應該被聲明為private (這不是語法錯誤而是語義錯誤)。 遺憾的是,Microsoft Visual C ++實現了一個非常古老的OpenMP規范(2002年3月起的2.0),它只允許以下語句在atomic結構中可接受:

x binop = expr
x ++
++ x
x -
- x

后來的版本包括x = x binop expr ,但即使在VS2012中,MSVC也永遠停留在OpenMP 2.0版本。 僅作比較,目前的OpenMP版本為3.1,我們預計在接下來的幾個月內會出現4.0。

在OpenMP 2.0中,您的語句應為:

#pragma omp atomic
sum += 4.0/(1.+ x*x);

但正如已經注意到的那樣,使用減少會更好(並且通常更快):

#pragma omp parallel for private(x) reduction(+:sum)
for (i=0; i<num_steps; i++)
{ 
    x = (i + .5)*step;
    sum = sum + 4.0/(1.+ x*x);  
}

(你也可以寫sum += 4.0/(1.+ x*x);

嘗試將sum = sum + 4.0/( 1. + x*x )改為sum += 4.0/(1.+ x*x) ,但我擔心這也不會起作用。 您可以嘗試拆分這樣的工作:

x = (i + .5)*step;
double xx = 4.0/(1.+ x*x);
#pragma omp atomic //this part contains error
sum += xx;

這應該有效,但我不確定它是否符合您的需求。

替換:

#pragma omp atomic

通過#pragma omp reduction(+:sum)#pragma omp critical

但我認為#pragma omp減少將是一個更好的選擇,因為你有sum + = Var;

這樣做:

x = (i + .5)*step;
double z = 4.0/(1.+ x*x);
#pragma omp reduction(+:sum)
sum += z;

您可能需要回顧一下#pragma而不是問題的真正解決方案。

#pragma是一組非標准的特定於編譯器的 ,並且大部分時間是特定於平台/系統的 - 這意味着在具有相同OS的不同機器上的行為可以是不同的,或者僅在具有不同設置的機器上的行為可以是不同的 - 用於預處理器。

因此,只有當您查看所選平台的編譯器的官方文檔時才能解決pragma的任何問題,這里有2個鏈接。

對於標准C / C ++, #pragma不存在。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM