2016-02-17 38 views
0

我正在研究cuda中的nbody模擬器。我想使用浮點類型來獲得速度優勢,但這使我的任務變得困難。我擔心的是說我有一個矢量< 10^20,10^20,10^20>,我想用畢達哥拉斯定理計算它的大小。我將不得不將每個組件分成10^40和32位,這只是無窮大。所以,即使最後的結果,當我把總和的平方根在範圍內,中間步驟會溢出。我在cuda math API中遇到了以下函數。 norm3df(x,y,z)。這是否會阻止我正在談論的中間步驟溢出?另外,我可能需要在主機和設備上使用此功能。行爲是否一樣?cuda數學函數norm3df溢出嗎?

+3

什麼會阻止你對自己進行測試?它的字面意思是20行代碼... – talonmies

+0

標準C/C++函數'hypot()'和CUDA的附加函數'rhypot()','norm3d()'和'rnorm3d()'的用途是精確的以避免中間計算中溢出或下溢的問題。由於'rhypot()','norm3d()'和'rnorm3d()'不是標準C/C++庫的一部分,所以你將無法在主機代碼中使用它們。您可能希望向主機編譯器的供應商建議將這些功能添加爲專有擴展。 – njuffa

+0

@ njuffa可能可以作爲答案。 FWIW我使用'norm3df()'測試了建議的測試用例,它給出了正確答案'173205081561134792704.0'。我很好奇爲什麼函數在頭文件和文檔中都被標記爲__host__ __device__,如果沒有宿主實現的話。我也很好奇'norm3d'如何避免中間溢出。它是否使用某種擴展來進行'double'算術? –

回答

2

標準C++數學函數庫包含函數hypot(),用於計算2D規範,同時避免中間計算中的過早下溢和溢出。由於3D規範也經常遇到,CUDA數學庫還提供了類似的功能norm3d()。在CUDA math API documentation的描述如下:

計算三維矢量p的長度在歐幾里德空間 而沒有不適當的溢出或下溢

此外,CUDA數學庫提供倒數規範功能rhypot()rnorm3d()在2D和3D矢量標準化時非常有用,因爲它們允許用更便宜的乘法代替昂貴的分區。

作爲norm3d()rhypot(),並rnorm3d()不是標準C++數學庫函數,它們不能在CUDA程序的主機部分中使用,作爲宿主代碼由主機工具鏈處理。 NVIDIA爲該設備提供數學庫支持。您可能希望向主機工具鏈的供應商提交增強請求,將這些有用的功能添加爲專有擴展,和/或遊說ISO C/C++委員會將其添加到標準的未來版本中。

以前我注意到,目前發佈CUDA頭文件似乎錯誤地將normd3d()和一些其他CUDA專用函數標記爲__host__ __device__,儘管事實上沒有主機實現。這似乎是一個錯誤,可能是由於過去將這些屬性應用於原型而造成的。

規範和互易規範函數在其內部計算中不需要更高的中間精度,這意味着對低吞吐量雙精度的GPU沒有負面的性能影響。相反,他們使用數學的巧妙重新排列,重新縮放操作數,並使用FMA實現他們的目標。它們不僅防止了不當的溢出和下溢,而且還應該比等效的樸素計算更準確。

直至幷包括CUDA 6.5版中,CUDA數學庫的實現細節都在CUDA頭文件math_functions.hmath_functions_dbl_ptx3.h可見的,所以任何人想誰得到的規範功能,內部細節可能需要一個更好的主意看這裏。