CUDA内核中usleep()的等价物?

CUDA内核中usleep()的等价物?,cuda,sleep,gpu,usleep,Cuda,Sleep,Gpu,Usleep,我想在CUDA内核中调用类似于usleep()的东西。基本目标是让所有的GPU内核休眠或忙碌等待数千次——这是我想为CUDA应用程序进行的一些健全性检查的一部分。我的尝试如下: #include <unistd.h> #include <stdio.h> #include <cuda.h> #include <sys/time.h> __global__ void gpu_uSleep(useconds_t wait_time_in_ms) {

我想在CUDA内核中调用类似于
usleep()
的东西。基本目标是让所有的GPU内核休眠或忙碌等待数千次——这是我想为CUDA应用程序进行的一些健全性检查的一部分。我的尝试如下:

#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;
}

显然,我不允许在内核中使用主机函数,如
usleep()
。有什么好的替代方法吗?

您可以通过读取
clock()
的循环来忙着等待

要等待至少10000个时钟周期:

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借用的。有关
clock()
工作原理的详细信息,请参见他的答案和CUDA C编程指南4.2中的B.10节。还有一个
clock64()
命令。

您可以在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;
}
\uuuuu全局\uuuuu无效时钟块(时钟*d\u o,时钟时钟计数)
{
clock_t start_clock=clock();
时钟偏移量=0;
while(时钟偏移量<时钟计数)
{
时钟偏移=时钟()-开始时钟;
}
d_o[0]=时钟偏移量;
}

我建议使用clock64()。clock()和clock64()以周期为单位,因此必须使用cudaDeviceProperties()查询频率。频率可以是动态的,因此很难保证精确的自旋环。

对于最新版本的CUDA,以及具有7.0或更高计算能力的设备(Volta、Turing、Ampere等),您可以使用
\u nanosleep()
原语:

void __nanosleep(unsigned ns);

这样就不必像以前的回答那样忙着睡觉了。

谢谢!我想使用clock64()来计算时间,这样我可以计算更长的时间,减少翻滚的影响。当我编译包含clock64()调用的CUDA内核时,会得到“错误:标识符“clock64”未定义”。当我使用clock()时,程序会正确编译。我正在使用NVCC4.0。根据谷歌的快速搜索,似乎clock64()应该在cuda/nvcc 4.0中。有没有关于如何解决这个问题的想法?您还需要计算能力>=2.0才能获得
clock64()
。有趣。我使用的是GTX480,nvidia将其列为具有计算能力2.0。您是否也编译为2.0?在Visual Studio 2010中,右键单击.cu文件,转到
配置属性| CUDA C/C++|设备|代码生成
,并检查它是否设置为
compute_20,sm_20
。啊哈,是的!就这样!我使用的是linux,所以我不使用VS2010。因此,我使用标志-gencode=arch=compute\u 20、code=sm\u 20编译,clock64()不再抛出编译时错误。
void __nanosleep(unsigned ns);