相当于CUDA内核中的usleep()?

sol*_*les 9 sleep cuda gpu usleep

我想usleep()在CUDA内核中调用类似的东西.基本目标是使所有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;
}
Run Code Online (Sandbox Code Playgroud)

当我尝试使用NVCC编译时出现以下错误:

error: calling a host function("usleep") from a __device__/__global__ 
       function("gpu_uSleep") is not allowed
Run Code Online (Sandbox Code Playgroud)

显然,我不允许使用usleep()内核等主机功能.什么是一个很好的替代品呢?

Gre*_*ith 21

你可以旋转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;
}
Run Code Online (Sandbox Code Playgroud)

我建议使用clock64().clock()和clock64()处于循环中,因此您必须使用cudaDeviceProperties()查询频率.频率可以是动态的,因此很难保证精确的自旋循环.


Rog*_*ahl 10

您可以忙着等待读取的循环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;
Run Code Online (Sandbox Code Playgroud)

注意:这是未经测试的.处理溢出的代码是@Pedro从这个答案中借来的.有关clock()工作原理的详细信息,请参阅"CUDA C编程指南4.2"中的答案和B.10部分.还有一个clock64()命令.

  • 你还需要计算能力> = 2.0来获得`clock64()`. (2认同)
  • 你还在编译2.0吗?在Visual Studio 2010中,右键单击.cu文件,转到"配置属性" CUDA C/C++ | 设备| 代码生成`并检查它是否设置为`compute_20,sm_20`. (2认同)

ein*_*ica 10

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

void __nanosleep(unsigned ns);
Run Code Online (Sandbox Code Playgroud)

这消除了旧答案中建议的忙碌睡眠的需要。