3

这是我在此的头一篇博文。耶!回到问题:

我正在学习如何使用 OpenMP。我的 IDE 是 Code::Blocks。我想改进我的一些旧程序。我需要确保结果将完全相同。似乎主线程中的“for”循环与其他线程中的优化方式不同。

例子:

#include <iostream>
#include <omp.h>
int main()
{
    std::cout.precision(17);
    #pragma omp parallel for schedule(static, 1) ordered
    for(int i=0; i<4; i++)
    {
        double sum = 0.;
        for(int j=0; j<10; j++)
        {
            sum += 10.1;
        }
        #pragma omp ordered
        std::cout << "thread " << omp_get_thread_num() <<  " says " << sum << "\n";
    }
    return 0;
}

生产

thread 0 says 101
thread 1 says 100.99999999999998579
thread 2 says 100.99999999999998579
thread 3 says 100.99999999999998579

我能否以某种方式确保所有线程都收到与我的单线程程序(未使用 OpenMP)收到的相同的优化?

编辑:

编译器是“来自 TDM-GCC(版本 4.9.2,32 位,SJLJ)的编译器和 GDB 调试器”,无论这意味着什么。这是 IDE 的“默认值”。我不熟悉编译器的差异。

提供的输出来自“Release”构建,它添加了“-O2”参数。

“-O”、“-O1”和“-O3”参数都不会产生“101”。

你可以试试我的 .exe 来自dropbox(zip 文件,还包含可能需要的 dll)

4

2 回答 2

2

发生这种情况是因为浮点或双精度数据类型不能表示某些数字,例如 20.2

#include <iostream>
int main()
{
    std::cout.precision(17);
    double a=20.2;
    std::cout << a << std::endl;
    return 0;
}

它的输出将是

20.199999999999999

有关这方面的更多信息,请参阅 添加两个浮点数时的意外输出

不知道为什么第一个线程不会发生这种情况,但是如果您删除 openMP,那么您也会得到相同的结果。

于 2016-03-01T15:44:48.487 回答
0

据我所知,这只是数值准确性。对于双值类型,您应该期望 16 位精度。

即结果是 101 +/- 1.e-16*101

这正是你得到的范围。除非你使用四倍精度之类的东西,否则这已经是最好的了。

于 2016-03-01T15:36:45.153 回答