Пример Lorenz с odeint и VexCL, дающий разные результаты на разных устройствах

Обновить:

Я запустил этот пример с другими системами. На Intel i7-3630QM, Intel HD4000 и Radeon HD 7630M все результаты одинаковы. С i7-4700MQ / 4800MQ результаты использования ЦП отличаются, когда OpenCL или 64-битный gcc используется из 32-битного gcc. Это результат того, что 64-битный gcc и OpenCl по умолчанию используют SSE, а 32-битный gcc использует 387 математических, по крайней мере, 64-битный gcc дает те же результаты, когда -mfpmath = 387 установлен. Поэтому я должен читать намного больше и экспериментировать с x86 с плавающей запятой. Спасибо всем за ваши ответы.


Я запустил пример системы Lorenz из раздела "Программирование CUDA и OpenCL: тематическое исследование с использованием современных библиотек C++" для десяти систем каждая на разных устройствах OpenCL и получаю разные результаты:

  1. Quadro K1100M (NVIDIA CUDA)

    R => XYZ
    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. Intel® R Graphics HD 4600 (Intel® OpenCL)

    R => XYZ
    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 с частотой 2,70 ГГц (Intel (R) OpenCL)

    R => XYZ
    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 и затем начинают расходиться.

Я запустил ту же область с odeint без VexCL и получаю результаты, близкие к результатам 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

Пример кода можно найти здесь: https://github.com/ddemidov/gpgpu_with_modern_cpp/blob/master/src/lorenz_ensemble/vexcl_lorenz_ensemble.cpp

Я не уверен, что я вижу здесь? Так как результаты процессора так близки друг к другу, это похоже на проблему с графическими процессорами, но, поскольку я новичок в OpenCL, мне нужно несколько советов, как найти основную причину этого.

2 ответа

Решение

Вы должны понимать, что у графических процессоров точность ниже, чем у процессоров. Это обычно, поскольку графический процессор предназначен для игр, где точные значения не являются целью проекта.

Обычно точность GPU составляет 32 бита. В то время как центральные процессоры имеют математику точности 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,

Я создал ветку stackru-23805423, чтобы проверить это. Ниже приведен вывод для разных устройств. Обратите внимание, что как процессоры, так и AMD GPU имеют стабильные результаты. Графические процессоры Nvidia также дают стабильные результаты, только они отличаются. Похоже, этот вопрос связан со стандартом IEEE-754 на графическом процессоре NVIDIA (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)
}

`` `

Другие вопросы по тегам