C++ Lorenz示例,odeint和VexCL在不同设备上产生不同的结果

C++ Lorenz示例,odeint和VexCL在不同设备上产生不同的结果,c++,opencl,odeint,vexcl,C++,Opencl,Odeint,Vexcl,更新: 我已经在其他系统上运行了这个示例。在Intel i7-3630QM、Intel HD4000和Radeon HD 7630M上,所有结果都是相同的。对于i7-4700MQ/4800MQ,当OpenCL或64位gcc与32位gcc使用时,CPU的结果不同。这是默认情况下使用SSE的64位gcc和OpenCl以及使用387 math的32位gcc的结果,当设置-mfpmath=387时,至少64位gcc会产生相同的结果。所以我必须读更多的书,并用x86浮点进行实验。谢谢大家的回答 我从“编

更新:

我已经在其他系统上运行了这个示例。在Intel i7-3630QM、Intel HD4000和Radeon HD 7630M上,所有结果都是相同的。对于i7-4700MQ/4800MQ,当OpenCL或64位gcc与32位gcc使用时,CPU的结果不同。这是默认情况下使用SSE的64位gcc和OpenCl以及使用387 math的32位gcc的结果,当设置-mfpmath=387时,至少64位gcc会产生相同的结果。所以我必须读更多的书,并用x86浮点进行实验。谢谢大家的回答


我从“编程CUDA和OpenCL:使用现代C++库的案例研究”对劳伦兹系统的例子进行了说明,在十个系统上,每个系统在不同的OpenCL设备上得到不同的结果:

  • Quadro K1100M(NVIDIA CUDA)

    R=>xyz
    0.100000=>-0.000000-0.0000000.000000
    5.644444=>-3.519254-3.519250 4.644452
    11.188890=>5.212534 5.212530 10.188904
    16.733334=>6.477303 6.477297 15.733333

    22.277779=>3.178553 2.579687 17.946903
    27.822224=>5.008720 7.753564 16.377680
    33.366669=>-13.381100-15.252210 36.107887
    38.911114=>4.256534 6.813675 23.838787
    44.455555=>-11.083726 0.691549 53.632290
    50.000000=>-8.624105-15.728293 32.516193

  • 英特尔(R)高清图形4600(英特尔(R)OpenCL)

    R=>xyz
    0.100000=>-0.000000-0.0000000.000000
    5.644444=>-3.519253-3.519250 4.644451
    11.188890=>5.212531 5.212538 10.188890
    16.733334=>6.477320 6.477326 15.733339

    22.277779=>7.246771 7.398651 20.735369
    27.822224=>-6.295782-10.615027 14.646572
    33.366669=>-4.132523-7.7732014.292910
    38.911114=>14.183139 19.582197 37.943520
    44.455555=>-3.129006 7.564254 45.736408
    50.000000=>-9.146419-17.006729 32.976696

  • 英特尔(R)核心(TM)i7-4800MQ处理器@2.70GHz(英特尔(R)OpenCL)

    R=>xyz
    0.100000=>-0.000000-0.0000000.000000
    5.644444=>-3.519254-3.519251 4.644453
    11.188890=>5.212513 5.212507 10.188900
    16.733334=>6.477303 6.477296 15.733332

    22.277779=>-8.295195-8.198518 22.271002
    27.822224=>-4.329878-4.022876 22.573458
    33.366669=>9.702943 3.997370 38.659538
    38.911114=>16.10549514.40139748.537579
    44.455555=>-12.551083-9.239071 49.378693
    50.000000=>7.377638 3.447747.542763

  • 如您所见,三个设备在R=16.733334的值上达成一致,然后开始发散

    我在没有VexCL的情况下使用odeint运行了相同的区域,得到的结果与CPU上运行OpenCL的结果非常接近:

    香草奥丁:

    R => x y z
    16.733334 => 6.47731 6.47731 15.7333
    22.277779 =>  -8.55303 -6.72512 24.7049
    27.822224 => 3.88874 3.72254 21.8227
    
    示例代码可在此处找到:


    我不确定我在这里看到了什么?由于CPU结果彼此非常接近,这看起来像是GPU的问题,但由于我是OpenCL新手,我需要一些关于如何找到这一问题的根本原因的指针。

    您必须了解GPU的精确度低于CPU。这是很常见的,因为GPU是为游戏而设计的,精确的值不是设计目标

    通常GPU的精度是32位。虽然CPU内部有48位或64位精度的数学运算,即使结果被剪切到32位存储


    您正在运行的操作严重依赖于这些微小的差异,从而为每个设备创建不同的结果。例如,该操作也会根据精度产生非常不同的结果:

    a=1/(b-c); 
    a=1/(b-c); //b = 1.00001, c = 1.00002  -> a = -100000
    a=1/(b-c); //b = 1.0000098, c = 1.000021  -> a = -89285.71428
    
    在您自己的结果中,您可以看到每个设备的不同,即使是低R值:

    5.644444 => -3.519254 -3.519250 4.644452
    5.644444 => -3.519253 -3.519250 4.644451
    5.644444 => -3.519254 -3.519251 4.644453
    
    但是,您声明“对于低值,结果一致到
    R=16
    ,然后开始发散”。这要看情况,因为它们并不完全相等,即使对于
    R=5.64

    ,我也创建了一个分支来测试这一点。下面是不同设备的输出。请注意,CPU和AMD GPU都有一致的结果。Nvidia GPU也有一致的结果,只是那些是不同的。这个问题似乎是相关的:

    ```


    ```

    看起来像是一个舍入/精度问题。您是否验证了所有使用类型(浮点、双精度等)的数据宽度是相同的?我已经对Quadro、HD4600和CPU使用了“浮点”格式的所有数据,对Quadro和CPU使用了“双精度”格式的所有数据(HD4600没有双精度支持)。结果是一样的。OpenCL FP类型不应该符合IEEE754吗?在本例中,GPU也以双精度(64位)运行。然而,这个答案有些道理,因为GPU上的FP操作可以给出与CPU不同的结果(例如)。由于在这个例子中计算的轨迹是混沌的,小的误差会以指数形式放大,最终导致完全不同的结果。对于R<23,系统不应该是混沌的,你应该有一个固定点。因此,结果看起来仍然很奇怪。至少不清楚为什么它们在R=16时开始出现分歧。*您可以通过这个小演示来了解我的意思:。因此,结果应该只在R值大于24时发散。我担心这个答案是不正确的。如上所述,不同的值只能在R>24时解释。对于较小的值,系统有一个固定点,该点应该几乎独立于浮点单位。在您的示例代码中,您运行100000次迭代,每次迭代都有多个和、乘法等。我不明白您为什么说它应该给出相同的结果。即使是0.00001的差异也可能在多次操作后产生完全不同的结果。
    1. Intel(R) Core(TM) i7 CPU         920  @ 2.67GHz (Intel(R) OpenCL)
    
    R = {
         0:  5.000000e+00  1.000000e+01  1.500000e+01  2.000000e+01  2.500000e+01
         5:  3.000000e+01  3.500000e+01  4.000000e+01  4.500000e+01  5.000000e+01
    }
    
    X = {
         0: ( -3.265986e+00 -3.265986e+00  4.000000e+00) (  4.898979e+00  4.898979e+00  9.000000e+00)
         2: (  6.110101e+00  6.110101e+00  1.400000e+01) ( -7.118047e+00 -7.118044e+00  1.900000e+01)
         4: (  9.392907e-01  1.679711e+00  1.455276e+01) (  5.351486e+00  1.051580e+01  9.403333e+00)
         6: ( -1.287673e+01 -2.096754e+01  2.790419e+01) ( -6.555650e-01 -2.142401e+00  2.721632e+01)
         8: (  2.711249e+00  2.540842e+00  3.259012e+01) ( -4.936437e+00  8.534876e-02  4.604861e+01)
    }
    
    1. Intel(R) Core(TM) i5-3570K CPU @ 3.40GHz (AMD Accelerated Parallel Processing)
    
    R = {
         0:  5.000000e+00  1.000000e+01  1.500000e+01  2.000000e+01  2.500000e+01
         5:  3.000000e+01  3.500000e+01  4.000000e+01  4.500000e+01  5.000000e+01
    }
    
    X = {
         0: ( -3.265986e+00 -3.265986e+00  4.000000e+00) (  4.898979e+00  4.898979e+00  9.000000e+00)
         2: (  6.110101e+00  6.110101e+00  1.400000e+01) ( -7.118047e+00 -7.118044e+00  1.900000e+01)
         4: (  9.392907e-01  1.679711e+00  1.455276e+01) (  5.351486e+00  1.051580e+01  9.403333e+00)
         6: ( -1.287673e+01 -2.096754e+01  2.790419e+01) ( -6.555650e-01 -2.142401e+00  2.721632e+01)
         8: (  2.711249e+00  2.540842e+00  3.259012e+01) ( -4.936437e+00  8.534876e-02  4.604861e+01)
    }
    
    1. Capeverde (AMD Accelerated Parallel Processing)
    
    R = {
         0:  5.000000e+00  1.000000e+01  1.500000e+01  2.000000e+01  2.500000e+01
         5:  3.000000e+01  3.500000e+01  4.000000e+01  4.500000e+01  5.000000e+01
    }
    
    X = {
         0: ( -3.265986e+00 -3.265986e+00  4.000000e+00) (  4.898979e+00  4.898979e+00  9.000000e+00)
         2: (  6.110101e+00  6.110101e+00  1.400000e+01) ( -7.118047e+00 -7.118044e+00  1.900000e+01)
         4: (  9.392907e-01  1.679711e+00  1.455276e+01) (  5.351486e+00  1.051580e+01  9.403333e+00)
         6: ( -1.287673e+01 -2.096754e+01  2.790419e+01) ( -6.555650e-01 -2.142401e+00  2.721632e+01)
         8: (  2.711249e+00  2.540842e+00  3.259012e+01) ( -4.936437e+00  8.534876e-02  4.604861e+01)
    }
    
    1. Tesla C1060 (NVIDIA CUDA)
    
    R = {
         0:  5.000000e+00  1.000000e+01  1.500000e+01  2.000000e+01  2.500000e+01
         5:  3.000000e+01  3.500000e+01  4.000000e+01  4.500000e+01  5.000000e+01
    }
    
    X = {
         0: ( -3.265986e+00 -3.265986e+00  4.000000e+00) (  4.898979e+00  4.898979e+00  9.000000e+00)
         2: (  6.110101e+00  6.110101e+00  1.400000e+01) ( -7.118047e+00 -7.118044e+00  1.900000e+01)
         4: (  7.636878e+00  2.252859e+00  2.964935e+01) (  1.373357e+01  8.995382e+00  3.998563e+01)
         6: (  7.163476e+00  8.802735e+00  2.839662e+01) ( -5.536365e+00 -5.997181e+00  3.191463e+01)
         8: ( -2.762679e+00 -5.167883e+00  2.324565e+01) (  2.776211e+00  4.734162e+00  2.949507e+01)
    }
    
    1. Tesla K20c (NVIDIA CUDA)
    
    R = {
         0:  5.000000e+00  1.000000e+01  1.500000e+01  2.000000e+01  2.500000e+01
         5:  3.000000e+01  3.500000e+01  4.000000e+01  4.500000e+01  5.000000e+01
    }
    
    X = {
         0: ( -3.265986e+00 -3.265986e+00  4.000000e+00) (  4.898979e+00  4.898979e+00  9.000000e+00)
         2: (  6.110101e+00  6.110101e+00  1.400000e+01) ( -7.118047e+00 -7.118044e+00  1.900000e+01)
         4: (  7.636878e+00  2.252859e+00  2.964935e+01) (  1.373357e+01  8.995382e+00  3.998563e+01)
         6: (  7.163476e+00  8.802735e+00  2.839662e+01) ( -5.536365e+00 -5.997181e+00  3.191463e+01)
         8: ( -2.762679e+00 -5.167883e+00  2.324565e+01) (  2.776211e+00  4.734162e+00  2.949507e+01)
    }
    
    1. Tesla K40c (NVIDIA CUDA)
    
    R = {
         0:  5.000000e+00  1.000000e+01  1.500000e+01  2.000000e+01  2.500000e+01
         5:  3.000000e+01  3.500000e+01  4.000000e+01  4.500000e+01  5.000000e+01
    }
    
    X = {
         0: ( -3.265986e+00 -3.265986e+00  4.000000e+00) (  4.898979e+00  4.898979e+00  9.000000e+00)
         2: (  6.110101e+00  6.110101e+00  1.400000e+01) ( -7.118047e+00 -7.118044e+00  1.900000e+01)
         4: (  7.636878e+00  2.252859e+00  2.964935e+01) (  1.373357e+01  8.995382e+00  3.998563e+01)
         6: (  7.163476e+00  8.802735e+00  2.839662e+01) ( -5.536365e+00 -5.997181e+00  3.191463e+01)
         8: ( -2.762679e+00 -5.167883e+00  2.324565e+01) (  2.776211e+00  4.734162e+00  2.949507e+01)
    }