【问题标题】:CUDA __host__ __device__ variablesCUDA __host__ __device__ 变量
【发布时间】:2016-01-18 01:01:10
【问题描述】:

在 CUDA 函数类型限定符 __device____host__ 可以一起使用,在这种情况下,该函数是为主机和设备编译的。这允许消除复制粘贴。但是,没有 __host__ __device__ 变量这样的东西。我正在寻找一种优雅的方式来做这样的事情:

__host__ __device__ const double common = 1.0;

__host__ __device__ void foo() {
    ... access common
}

__host__ __device__ void bar() {
    ... access common
}

我发现以下代码符合并运行时没有错误。 (所有结果都是在 Ubuntu 14.04 上使用 CUDA 7.5 和 gcc 4.8.4 作为主机编译器获得的)

#include <iostream>

__device__ const double off = 1.0;

__host__ __device__ double sum(int a, int b) {
    return a + b + off;
}

int main() {
    double res = sum(1, 2);
    std::cout << res << std::endl;
    cudaDeviceReset();
    return 0;
}

$ nvcc main.cu -o main && ./main
4

事实上,nvcc --cuda main.cu 将 cu-file 翻译成这样:

...
static const double off = (1.0);
# 5 "main.cu"
double sum(int a, int b) {
# 6 "main.cu"
return (a + b) + off;
# 7 "main.cu"
}
# 9 "main.cu"
int main() {
# 10 "main.cu"
double res = sum(1, 2);
# 11 "main.cu"
(((std::cout << res)) << (std::endl));
# 12 "main.cu"
cudaDeviceReset();
# 13 "main.cu"
return 0;
# 14 "main.cu"
}
...

但是,毫不奇怪,如果声明变量 off 时没有 const 限定符 (__device__ double off = 1.0),我会得到以下输出:

$ nvcc main.cu -o main && ./main
main.cu(7): warning: a __device__ variable "off" cannot be directly read in a host function

3

那么,回到最初的问题,我可以依靠全局__device__ const 变量的这种行为吗?如果没有,还有哪些其他选择?

UPD顺便说一句,上述行为不会在 Windows 上重现。

【问题讨论】:

    标签: c++ cuda gpgpu nvcc


    【解决方案1】:

    对于普通浮点或整数类型,只需在全局范围内将变量标记为 const 就足够了:

    const double common = 1.0;
    

    然后它应该可以在任何后续函数中使用,无论是主机、__host____device__ 还是 __global__

    这在文档here 中得到支持,但受到各种限制:

    让“V”表示具有 const 限定类型且没有执行空间注释的命名空间范围变量或类静态成员变量(例如,__device____constant__、@987654329 @)。 V 被认为是一个宿主代码变量。

    V 的值可以直接用在设备代码中,如果 V 在使用点之前已经用常量表达式初始化,并且 它具有以下类型之一:

    • 内置浮点类型,Microsoft 编译器用作宿主编译器时除外,
    • 内置整型。

    设备源代码不能包含对V的引用或取V的地址。

    在其他情况下,一些可能的选择是:

    1. 使用编译器宏定义的常量:

      #define COMMON 1.0
      
    2. 如果变量的选择范围是离散且有限的,请使用模板。

    3. 对于其他选项/情况,可能需要管理变量的显式主机和设备副本,例如使用设备上的__constant__ 内存,以及主机上的相应副本。 __host__ __device__ 函数中访问变量的主机和设备路径可以根据 nvcc 编译器宏区分行为(例如 #ifdef __CUDA_ARCH__ ...

    【讨论】:

      猜你喜欢
      • 2015-12-10
      • 1970-01-01
      • 1970-01-01
      • 2020-10-29
      • 1970-01-01
      • 2021-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多