【问题标题】:Lorenz example with odeint and VexCL yielding different results on different devices使用 odeint 和 VexCL 的 Lorenz 示例在不同的设备上产生不同的结果
【发布时间】:2014-05-22 11:22:59
【问题描述】:

更新:

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


我已经针对不同 OpenCL 设备上的十个系统运行了“编程 CUDA 和 OpenCL:使用现代 C++ 库的案例研究”中的 Lorenz 系统示例,并且得到了不同的结果:

  1. Quadro K1100M (NVIDIA CUDA)

    R => x y z
    0.100000 => -0.000000 -0.000000 0.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

  2. 英特尔(R) 高清显卡 4600(英特尔(R) OpenCL)

    R => x y z
    0.100000 => -0.000000 -0.000000 0.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.773201 14.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

  3. Intel(R) Core(TM) i7-4800MQ CPU @ 2.70GHz(Intel(R) OpenCL)

    R => x y z
    0.100000 => -0.000000 -0.000000 0.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.105495 14.401397 48.537579
    44.455555 => -12.551083 -9.239071 49.378693
    50.000000 => 7.377638 3.447747 47.542763

如您所见,三个设备在最高 R=16.733334 的值上达成一致,然后开始出现分歧。

我在没有 VexCL 的情况下使用 odeint 运行了相同的区域,并获得了接近 CPU 运行时 OpenCL 的结果的结果:

香草 odeint:

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

示例代码可以在这里找到:https://github.com/ddemidov/gpgpu_with_modern_cpp/blob/master/src/lorenz_ensemble/vexcl_lorenz_ensemble.cpp

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

【问题讨论】:

  • 看起来像一个舍入/精度问题。您是否验证过所有使用的类型(浮点型、双精度型等)的数据宽度都相同?
  • 我已经将 Quadro、HD4600 和 CPU 的所有内容都设置为“float”,Quadro 和 CPU 的所有内容都设置为“double”(HD4600 不支持双精度)。结果是一样的。 OpenCL FP 类型不应该符合 IEEE754 吗?

标签: c++ opencl odeint vexcl


【解决方案1】:

您必须了解 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

【讨论】:

  • 在此示例中,GPU 也以双精度(64 位)运行。然而,这个答案有一些道理,因为 GPU 上的 FP 操作可以给出与 CPU 不同的结果(例如developer.download.nvidia.com/assets/cuda/files/…)。由于本例中计算的轨迹是混乱的,因此小错误会呈指数级增长,最终导致完全不同的结果。
  • R
  • 你可以玩这个小演示来了解我的意思:gist.github.com/headmyshoulder/8a97787d63da8b8ffa32。因此,结果应该只在 R 值大于 24 时出现分歧。
  • 我担心这个答案是不正确的。如上所述,只能在 R>24 时解释不同的值。对于较小的值,系统有一个固定点,该点应该几乎独立于浮点单元。
  • 在您的示例代码中,您运行了 100000 次迭代,每个迭代都有多个求和、乘法等。我不明白您为什么说它应该给出相同的结果。经过这么多操作,即使是 0.00001 的差异也会产生完全不同的结果。
【解决方案2】:

我创建了一个stackoverflow-23805423 分支来测试它。下面是不同设备的输出。请注意,CPU 和 AMD GPU 的结果一致。 Nvidia GPU 也有一致的结果,只是那些不同。这个问题似乎是相关的:IEEE-754 standard on NVIDIA GPU (sm_13)

```

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)
}

```

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 2018-03-27
    相关资源
    最近更新 更多