簡體   English   中英

在以 4000 作為除數的 cuda gpu 上計算快速模運算。 eq: (ab)%4000

[英]Calculate fast modulo arithmetic on cuda gpu having 4000 as divisor . eq: (a-b)%4000

我正在嘗試在 pascal 架構(nvidia 1060)上優化 cuda 中的模運算,因為傳統的 (%) 運算符會顯着減慢代碼速度。 我看過一些優化的例子,但它們僅在除數是 2 或 (2^k)-1 的冪時才適用。 在我的代碼中,除數是 4000。

好心,建議我一個優化的方法來計算下面的等式中的余數

  remainder = (a-b)%4000

我假設您可以證明與使用編譯器優化和使用位掩碼的模 4096 相比有多慢? 如果它只慢 2 到 3 倍,你真的無法擊敗它,

為了好玩,因為我懷疑你會超過上述指標:

在現代處理器上,除法通常不會那么慢,但要注意的一件事是,當它變慢時,它取決於被除數的大小。 另一個是無符號除法比有符號除法更快。

減少數字大小的一種方法是考慮如何建立模數。

如果你執行 div 和 mod 4096,那么你可以問,什么是 4096 mod 4000 = 96。所以你的原始數字的 mod 4000 是(96 * div4096 + mod4096) mod 4000其中這些是比你開始時更小的數字並且可能,只是也許更快,因為它使用更少的位。 注意,在這個階段你也可以使用4000 = 32 * 125的關系,所以低5位將是模的低5位,你只需要除以125。

現在在 8 位處理器上,除以小於 128 比除以更大的數字要快得多! 不過,我懷疑您是否擁有其中之一。

另一種選擇是使用高精度逆乘法。 具有較差除法的處理器可能具有可接受的乘法。 這個技巧是你可以使用最大的整數來執行 2^n/4000 的乘法,其中 n 是大整數類型寬度的一半,或者可以更高,如果你需要除以的最大數是小於 2^n。 該數字的頂部 (>>n) 是除法的(近似)結果,如果分辨率足夠高,應該“足夠接近”。 再次將該值乘以 4000 並從原始值中減去,您的模數為 +/- 4000 的幾倍,這是 2 次大乘法與 1 次小除法的成本。 在 intel 上有一個乘法輸入 16 位值ax*dx並輸出 32 位值dx:ax ,並為64-bit edx*eax => 128 bit edx:eax復制,但當然是 intel 386 及更高版本無論如何都有足夠快的分歧。

還有另一種通用方法,當您想要的除數接近 2 的冪時,在您的情況下,4000 是 4096 的 97%:

loop:
  do the div4096 by bit shift
  multiply 4000 by div4096
  subtract
until result < 3*4096 
use if statement to get final mod value

這將執行重復乘法,但每次,div4096 都是 div4000 的低估計量,降低 3%,0.03,大約 64 位或 6 位中的 1 個,在下一次迭代時會被清除,因此它可能會循環此循環 7 次對於 64 位最大值。 如果 mul 比 div 快 7*,那么你就贏了。 如果您想要 mod 或 div 的值比 2 的冪低幾個百分點,那么迭代次數就太高了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM