簡體   English   中英

CUDA中的一些數學運算

[英]some mathematical operations in CUDA

我有一個包含0,1和2的2D矩陣。我正在編寫一個cuda內核,其中線程數等於矩陣大小,每個線程將對矩陣的每個元素進行操作。 現在,我需要可以保持0和1的數學運算,但是將2轉換為1.這是一個數學運算,沒有任何if-else,它將執行以下轉換:0 - > 0; 1 - > 1; 2 - > 1。 是否有任何可能的方法使用數學運算符進行上述轉換。 任何幫助將非常感激。 謝謝。

這不是一個問題。

int A;
// set A to 0, 1, or 2
int a = (A + (A>>1)) & 1;
// a is now 0 if A is 0, or 1 if A is 1 or 2

或作為宏:

#define fix01(x) ((x+(x>>1))&1)

int a = fix01(A);

這似乎也有效:

#define fix01(x) ((x&&1)&1)

我不知道布爾AND運算符( && )的使用是否符合您對“數學運算”的定義。

由於問題是關於“數學”函數,我建議使用以下二階多項式:

int f(int x) { return ((3-x)*x)/2; }

但是如果你想避免分支以最大化速度:自PTX ISA 1.0以來有一條min指令。 (參見PTX ISA 3.1手冊中的表36)。所以下面的CUDA代碼

__global__ void test(int *x, int *y)
{
    *y = *x <= 1 ? *x : 1;
}

在我的測試中編譯到下面的PTX匯編程序(剛從CUDA 5調用nvcc而沒有任何arch選項)

    code for sm_10
            Function : _Z4testPiS_
    /*0000*/     /*0x1000c8010423c780*/     MOV R0, g [0x4];
    /*0008*/     /*0xd00e000580c00780*/     GLD.U32 R1, global14 [R0];
    /*0010*/     /*0x1000cc010423c780*/     MOV R0, g [0x6];
    /*0018*/     /*0x30800205ac400780*/     IMIN.S32 R1, R1, c [0x1] [0x0];
    /*0020*/     /*0xd00e0005a0c00781*/     GST.U32 global14 [R0], R1;

所以使用條件?的min()實現:實際上編譯為單個IMIN.S32 PTX指令而沒有任何分支。 因此,我建議將其用於任何實際應用:

int f(int x) { return x <= 1 ? x : 1; }

但回到僅使用非分支操作的問題:

在C中獲得此結果的另一種形式是使用兩個非運算符:

int f(int x) { return !!x; }

或者簡單地與零比較:

int f(int x) { return x != 0; }

(!和!=的結果保證為0或1,比較C.5標准的第6.5.3.3節第5節和第6.5.9節第3節,ISO / IEC 9899:1999。此保證也是在CUDA舉行。)

暫無
暫無

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

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