Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C OpenMP中奇怪的浮点行为_C_Debugging_Floating Point_Openmp - Fatal编程技术网

C OpenMP中奇怪的浮点行为

C OpenMP中奇怪的浮点行为,c,debugging,floating-point,openmp,C,Debugging,Floating Point,Openmp,我正在运行以下OpenMP代码 #pragma omp parallel shared(S2,nthreads,chunk) private(a,b,tid) { tid = omp_get_thread_num(); if (tid == 0) { nthreads = omp_get_num_threads(); printf("\nNumber of threads =

我正在运行以下OpenMP代码

        #pragma omp parallel shared(S2,nthreads,chunk) private(a,b,tid)
    {
        tid = omp_get_thread_num();
        if (tid == 0)
        {
            nthreads = omp_get_num_threads();
            printf("\nNumber of threads = %d\n", nthreads);
        }
        #pragma omp for schedule(dynamic,chunk) reduction(+:S2)
        for(a=0;a<NREC;a++){
            for(b=0;b<NLIG;b++){
                S2=S2+cos(1+sin(atan(sin(sqrt(a*2+b*5)+cos(a)+sqrt(b)))));
            }
        } // end for a
    } /* end of parallel section */
#pragma omp并行共享(S2,nthreads,chunk)私有(a,b,tid)
{
tid=omp_get_thread_num();
如果(tid==0)
{
nthreads=omp_get_num_threads();
printf(“\n线程数=%d\n”,n个线程);
}
#用于计划(动态、块)缩减的pragma omp(+:S2)

对于(a=0;a而言,浮点数的加减顺序会影响精度

举个简单的例子,假设您的计算机存储2个十进制数字,并且您正在计算1+0.04+0.04的值

  • 如果先做左加法,得到1.04,四舍五入为1。第二次加法将再次得到1,因此最终结果为1

  • 如果你先做正确的加法,得到0.08。加上1,得到1.08,四舍五入为1.1

为了获得最大的准确度,最好从小到大添加值

另一个原因可能是CPU上的浮点寄存器可能比主存中的浮点寄存器包含更多的位。因此,如果某个中间结果缓存在寄存器中,则更准确,但如果将其换出内存,则会被截断


另请参见。

众所周知,当减去两个大值(或添加两个具有不同符号的大值)时,机器浮点操作存在缺陷结果产生微小差异。因此,对振荡符号序列求和可能会在每次迭代中引入严重错误。另一个有缺陷的情况是,当两个操作数的大小相差很大时,较小的操作数实际上会自动抵消。
将正操作数和负操作数分开,分别对每个组执行求和,然后对组结果进行加(减)运算,这可能很有用。

如果准确性至关重要,则可能需要对每个组进行预排序,并在每个组内部执行两次求和。第一次求和将从中心向最大的(头部),第二次求和将从最小的(尾部)朝向中心。结果组总和将是部分运行的总和。

True。此外,还原中的加法顺序也会影响结果,尤其是当值之间的差异较大时。这实际上更重要,并且需要编辑。谢谢!您可以详细了解此总和的运算顺序的重要性通过串行求和,但反转循环,我得到了大约0.1%的差异。如果你将求和中的项绘制为a和b的函数,你可以看到发生了什么(遗憾的是,你不能将图像附加到注释上)-求和是令人难以置信的振荡,所有这些+s和-s抵消的程度将敏感地取决于求和的顺序。