2015-09-04 59 views
0

Cuda printf似乎並不尊重__syncthreads(),即使在同一個塊中也是如此。特別是,如果我的線程在調用__syncthreads和其他東西之前打印出某些東西,那麼我會希望如果我的線程打印出某些東西,那麼我會看到之前的所有打印後跟所有打印後的東西。這不是我所看到的,我想知道我是否錯過了一些東西。這裏是我的代碼示例:cuda printf和__syncthreads排序

#include <stdio.h> 
#include <cuda_runtime_api.h> 

#define ROUND_UP(x) (((x)&1) + ((x)>>1)) 
__global__ void test() 
{ 
    int t = threadIdx.x, last = blockDim.x; 
    int offset = ROUND_UP(last); 

    while (last > 1 && t + offset < last) { 
    offset = ROUND_UP(offset); 
    last = ROUND_UP(last); 
    __syncthreads(); 
    if (t == 33 || t == 64) 
     printf("A: t = %d, last = %d\n", t, last); 
    } 
    while (last > 1) { 
    last = ROUND_UP(last); 
    __syncthreads(); 
    if (t == 33 || t == 64) 
     printf("B: t = %d, last = %d\n", t, last); 
    } 
} 

int main() 
{ 
    test<<<1,66>>>(); 
    cudaDeviceSynchronize(); 
    return 0; 
} 

這將導致以下的輸出:

B: t = 64, last = 33 
B: t = 64, last = 17 
B: t = 33, last = 33 
B: t = 64, last = 9 
B: t = 33, last = 17 
B: t = 64, last = 5 
B: t = 33, last = 9 
B: t = 64, last = 3 
B: t = 33, last = 5 
B: t = 64, last = 2 
B: t = 33, last = 3 
B: t = 64, last = 1 
B: t = 33, last = 2 
B: t = 33, last = 1 

當我讀到這,螺紋64已退出螺紋33已經進入它第二次前兩次__syncthreads。這怎麼可能?

+2

您正在依賴threadIdx的條件塊中使用syncthreads。我懷疑你的代碼可能在這方面被破壞。 –

+0

@Robert,循環的構建意圖是不管threadIdx如何,syncthreads將被調用相同的次數。 ROUND_UP宏將其輸入減半,向上舍入,所以最後從66,33,17,9,5,3,2,1開始。每次,synthreads被調用一次,儘管它被調用的while循環因線程而異IDX。 –

+0

@JonathanShaw:對不起,在手機屏幕上很難找到。請記住,CUDA中的內存事務是「火併且遺忘」的,並且內存控制器清除事務請求的順序未定義,這可能會影響您看到的順序。一般情況下,使用printf的方式可能不被推薦 – talonmies

回答

1

the documentation

__syncthreads()允許在條件代碼中,但只有當條件估值同樣橫跨整個線程塊

OP的代碼似乎違反了這一要求。根據OP的陳述,重構代碼以解決這個問題導致令人費解的printf觀察消失。

如果在此區域存在疑慮,cuda-memcheck工具提供synccheck選項,該選項可用於在發散代碼中查找__syncthreads()的無效用法。