OpenMP平行还原(最小)结果不正确

发布于 2025-01-27 12:39:07 字数 1960 浏览 3 评论 0原文

我正在使用OpenMP减少(Min)来在所有参与线程上并行部分中获取最少的锁定获取数量。 在平行部分中打印每个线程计数器时,我会得到正确的结果,但是在平行部分之后,最小计数器在0。 这是代码:

    int counter = 0, maxV, minV;
    bool _continue = true;  //variable to indicate when one second is over

    #pragma omp parallel private(id) shared(lock, _continue) reduction(min:minV) reduction(+:counter) reduction(max:maxV)
    {
        id = omp_get_thread_num();
        
        if(id == 0)
        {
            auto start = std::chrono::high_resolution_clock::now(); //start time measurement
            while(_continue)
            {
                auto finish = std::chrono::high_resolution_clock::now();
                std::chrono::duration<double, std::micro> elapsed = finish - start;
                if(elapsed.count() > std::chrono::microseconds(sec).count())
                {
                    _continue = false;
                }
            }
        }
        else
        {
            while(_continue) //during timeframe, try to obtain lock as often as possible
            {
                lock.lock(id);
                lock.unlock(id);
                counter++;
            }
            minV = counter;
            maxV = counter;
        }
        #pragma omp critical
        {
            std::cout << id << ": " << minV << std::endl; 
        }
        
    }
    std::cout << minV << std::endl;

典型输出类似:

0: 2147483647
7: 256985
4: 255973
1: 256975
6: 255740
5: 256658
3: 256856
2: 256943
0

因此,即使对于线程0,也没有获取锁的线程,而是花时间,MINV在还原列表类型(int)中正确初始化为最大代表数字(INT) 。

根据我选择的编译器选项,我可以将MINV的结果(COUT中的最后一行)更改为以下值(总是错误的...):

MINV = 32767 | -std = C ++ 14 -Fopenmp

minv = 0 | -std = C ++ 14 -Fopenmp -O3

minv = 32766 | -std = C ++ 14 -Fopenmp -Wall

Minv = 32767 | -STD = C ++ 14 -Fopenmp -wall -Pedantic -March =本机-FConcepts,

所以我认为它与我的编译器选项有关吗?奇怪的是,最高和降低似乎有效...

任何帮助都将受到赞赏。

i am using OpenMP reduction(min) to get the minimum number of lock acquisitions in a parallel section over all participating threads.
When printing each threads counter inside the parallel section, I get correct results but after the parallel section, the min counter is at 0.
This is the code:

    int counter = 0, maxV, minV;
    bool _continue = true;  //variable to indicate when one second is over

    #pragma omp parallel private(id) shared(lock, _continue) reduction(min:minV) reduction(+:counter) reduction(max:maxV)
    {
        id = omp_get_thread_num();
        
        if(id == 0)
        {
            auto start = std::chrono::high_resolution_clock::now(); //start time measurement
            while(_continue)
            {
                auto finish = std::chrono::high_resolution_clock::now();
                std::chrono::duration<double, std::micro> elapsed = finish - start;
                if(elapsed.count() > std::chrono::microseconds(sec).count())
                {
                    _continue = false;
                }
            }
        }
        else
        {
            while(_continue) //during timeframe, try to obtain lock as often as possible
            {
                lock.lock(id);
                lock.unlock(id);
                counter++;
            }
            minV = counter;
            maxV = counter;
        }
        #pragma omp critical
        {
            std::cout << id << ": " << minV << std::endl; 
        }
        
    }
    std::cout << minV << std::endl;

The typical output is something like:

0: 2147483647
7: 256985
4: 255973
1: 256975
6: 255740
5: 256658
3: 256856
2: 256943
0

So even for thread 0, the thread that is not acquiring the lock but just taking the time, the minV is correctly initialized as largest representable number in the reduction list item type (int).

Depending on what compiler options I choose, I can alter the result of minV (last line in cout) to the following values (always wrong...):

minV = 32767 | -std=c++14 -fopenmp

minV = 0 | -std=c++14 -fopenmp -O3

minV = 32766 | -std=c++14 -fopenmp -Wall

minV = 32767 | -std=c++14 -fopenmp -Wall -pedantic -march=native -fconcepts

So I assume it has something to do with my compiler options? Strangely though, the max and sum reduction appear to work fine...

Any help is appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绝對不後悔。 2025-02-03 12:39:07

您在OMP内部使用的INIT值与用户代码中的初始值之间存在混淆。部分减少是用内部值完成的,但是在某个时候,还必须对用户供使用的初始值进行减少。如果您不设置它,可能会发生任何事情。

这是一张可爱的图片: https://theartofhpc.com/pcce.com/pcse/pcse/omp-reduction。 html#initialValueForreductions

You have a confusion between the init value that OMP uses internally, and the init value from the user code. The partial reductions are done with the internal value, but at some point there also has to be a reduction against the user-supplied initial value. If you don't set that, anything can happen.

Here is a cute picture: https://theartofhpc.com/pcse/omp-reduction.html#Initialvalueforreductions

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文