2012-06-26 32 views
8

我想在CUDA內核中調用類似usleep()的東西。基本目標是使所有GPU內核在幾毫秒內都處於睡眠或等待狀態 - 這是我想爲CUDA應用程序執行某些理智檢查的一部分。我在做這個嘗試是如下:CUDA內核中usleep()的等價物?

#include <unistd.h> 
#include <stdio.h> 
#include <cuda.h> 
#include <sys/time.h> 

__global__ void gpu_uSleep(useconds_t wait_time_in_ms) 
{ 
    usleep(wait_time_in_ms); 
} 

int main(void) 
{ 
    //input parameters -- arbitrary 
    // TODO: set these exactly for full occupancy 
    int m = 16; 
    int n = 16; 
    int block1D = 16; 
    dim3 block(block1D, block1D); 
    dim3 grid(m/block1D, n/block1D); 

    useconds_t wait_time_in_ms = 1000; 

    //execute the kernel 
    gpu_uSleep<<< grid, block >>>(wait_time_in_ms); 
    cudaDeviceSynchronize(); 

    return 0; 
} 

我收到以下錯誤,當我嘗試編譯此使用NVCC:顯然

error: calling a host function("usleep") from a __device__/__global__ 
     function("gpu_uSleep") is not allowed 

,我不能使用主機功能,如內核中的usleep()。什麼會是一個很好的選擇呢?

回答

9

您可以忙於等待循環,該循環的內容爲clock()

要等待至少10,000個時鐘週期:

clock_t start = clock(); 
clock_t now; 
for (;;) { 
    now = clock(); 
    clock_t cycles = now > start ? now - start : now + (0xffffffff - start); 
    if (cycles >= 10000) { 
    break; 
    } 
} 
// Stored "now" in global memory here to prevent the 
// compiler from optimizing away the entire loop. 
*global_now = now; 

注:這是未經測試。處理溢出的代碼是由@Pedro從this answer中借用的。有關clock()如何工作的詳細信息,請參閱CUDA C編程指南4.2中的答案和B.10節。還有一個clock64()命令。

+0

謝謝!我想使用clock64(),這樣我可以計算更長的時間並減少滾動的影響。當我編譯包含clock64()調用的CUDA內核時,我得到「error:identifier」clock64「未定義。」當我使用clock()時,程序編譯正確。我正在使用nvcc 4.0。基於快速谷歌搜索,看起來clock64()應該是在cuda/nvcc 4.0中。有關如何解決這個問題的任何想法? – solvingPuzzles

+2

您還需要計算能力> = 2.0才能獲得'clock64()'。 –

+0

有趣。我使用的是GTX480,nvidia列出了具有計算能力2.0的GTX480。 – solvingPuzzles

17

你可以在clock()或clock64()上旋轉。在CUDA SDK concurrentKernels樣品確實這樣做了以下內容:

__global__ void clock_block(clock_t *d_o, clock_t clock_count) 
{ 
    clock_t start_clock = clock(); 
    clock_t clock_offset = 0; 
    while (clock_offset < clock_count) 
    { 
     clock_offset = clock() - start_clock; 
    } 
    d_o[0] = clock_offset; 
} 

我建議使用clock64()。 clock()和clock64()是循環的,所以你將不得不使用cudaDeviceProperties()來查詢頻率。頻率可以是動態的,因此很難保證準確的旋轉循環。

+3

+1關於頻率的評論 –

+1

永遠不會太晚,無法提供一個可靠的答案,特別是因爲內核名稱太有趣了。那是故意的嗎? – JorenHeit