回答
這可能有一個簡單的答案。 CUDA程序經常使用float變量類型,因爲它可能比double快得多。評估操作的順序可以顯着影響浮點計算的最終值;這不是CUDA的獨特之處,但是您可能會注意到這些影響特別尖銳,因爲它是一個大規模並行的範例(並行性帶有非確定性,至少在執行像全局縮減時)。
編輯:只是要清楚,它是一個必要(雖然不足)的條件,即CUDA不保證相同的內核將在多次執行中以相同的順序執行。如果CUDA確實保證了這一點,那麼算術運算的執行順序就不可能因運行而不同,因此,對於相同的浮點運算不會有不同的值。
這是一個簡單的C程序,演示了上述說明。試試代碼
#include <stdio.h>
int main()
{
float a = 100.0f, b = 0.00001f, c = 0.00001f;
printf("a + b + c = %f\n", a + b + c);
printf("b + c + a = %f\n", b + c + a);
printf("a + b + c == b + c + a ? %d\n", (a + b + c) == (b + c + a));
return 0;
}
在Linux上,看看你得到了什麼(我正在使用64位RHEL 6和gcc版本4.4.4-13)。我的輸出如下:
[[email protected] directory]# gcc add.c -o add
[[email protected] directory]# ./add
a + b + c = 100.000015
b + c + a = 100.000023
a + b + c == b + c + a ? 0
編輯:請注意,雖然此程序可能意味着潛在的問題是,浮點加法是不可交換的,它實際上是浮點加法是非的情況下關聯(因爲C從左向右評估加法運算,所以第一次加法按照(a + b)+ c執行,第二次按照(b + c)+ a執行)。非關聯性的原因是浮點表示只能表示有限數量的有限數字(以2爲底,但基本10系統的討論基本上是等價的)。例如,如果只能表示三位有效數字,則可以得到(100 + 0.5)+0.5 = 100 + 0.5 = 100,而100 +(0.5 + 0.5)= 100 + 1 = 101。在第一種情況下,結果100 + 0.5必須被截斷(或可能被舍入),因爲不可能僅用三位有效數字來表示中間值100.5。
這種現象有許多重要的含義;例如,您將通過按大小(指數)的升序添加數字來得到更準確的答案。真正的收穫是,除非計算按照相同的順序執行,否則不應期望結果相同,這可能很難保證在真實的GPU上使用CUDA。
這將如何解釋從運行到運行在相同輸入數據上的變化,其他要求硬件隨機地重新排序運行的執行?根據我的經驗,雖然執行順序不能事先確定,但硬件不會隨機化相同代碼的執行順序。 – talonmies 2012-02-14 21:09:08
@talonmies我的印象並不是CUDA保證您將從運行到運行獲得相同的執行順序。雖然它可能不會(有意)隨機化執行,但可能會受到某種干擾或某種干擾。如果CUDA確實提供了這樣的保證,那麼我會同意這個答案是不正確的,並將刪除它。 – Patrick87 2012-02-14 21:21:42
可能每次發佈第一個發佈的塊到不同的多處理器,並且如果跨多處理器的塊數量不均勻,那麼執行順序可能會在運行之間略有不同。如果涉及到原子,並且內存地址在不同運行中有所不同,則可能會更多地改變執行順序。 BTW @ Patrick87,爲了讓您對浮點執行方差的解釋真正正確,您可能想指出所有這一切的真正原因是「浮點算術是非關聯性的」。 – harrism 2012-02-15 00:17:13
- 1. CUDA fft與MATLAB的不同結果fft
- 2. Parallel.ForEach每次給出不同的結果
- 3. Xcode每次運行C++測試都會給出不同的結果
- 4. Ionic zip每次都會給出不同的字節數組
- 5. AForge FFT給出的結果不同於加速FFT
- 6. 每次運行同一scrapy項目時都會產生不同的結果
- 7. 每次調用時都會產生不同的結果
- 8. Matlab中的FFT和numpy/scipy給出了不同的結果
- 9. 手冊FFT不給我相同的結果,FFT
- 10. 一次性鍵盤每次都給出相同的答案
- 11. URL每次都會返回相同的結果
- 12. Rhino Mocks,每執行一次stubbed方法都會返回不同的結果
- 13. 在不同的數據庫上下文中的相同查詢會給出不同的結果
- 14. 看似相同的代碼不會給出相同的結果
- 15. SQL Server Select Distinct Returns每次都有不同的結果
- 16. GetHashCode()在不同的服務器上給出不同的結果?
- 17. JSON.stringify在不同的URL上給出不同的結果
- 18. numpy中的FFT與MATLAB中的FFT沒有相同的結果
- 19. CUDA C/C++:相同的可執行文件給出了第一次運行的不同結果
- 20. PHP執行不會給出與cmd相同的結果
- 21. pyCaffe不會給出與命令行界面相同的結果
- 22. GetElementByName不會給出與GetElementById相同的結果
- 23. SQL Query每次運行時都會返回不同的數據集(不一致)
- 24. ioctl()每次給出不同的大小
- 25. 每次接到呼叫時都會發出不同的聲音
- 26. 爲什麼此輸出每次都會返回不同的值?
- 27. 爲什麼RANSAC每次在同一個點雲上運行時會給我不同的結果?
- 28. 在同一數據庫上的相同查詢在OAS 10.1.3上給出了不同的結果
- 29. CUDA在不同平臺上的不同結果
- 30. 代碼在不同的值上給出了相同的結果
這很有趣。你能發佈一些代碼來告訴我們你在做什麼嗎? – 2012-02-14 19:56:06
很可能是因爲你每次都在做某種微妙的變化。向我們展示一個展示此問題的最小示例。 – Bart 2012-02-14 20:00:31
除了發佈一些代碼,你需要更精確地描述「微妙不同」。 – 2012-02-14 20:07:02