【问题标题】:Fastest (or most elegant) way of passing constant arguments to a CUDA kernel将常量参数传递给 CUDA 内核的最快(或最优雅)方式
【发布时间】:2015-10-12 16:45:53
【问题描述】:

假设我想要一个需要做很多事情的 CUDA 内核,但有一些圆顶参数对于所有内核都是不变的。此参数作为输入传递给主程序,因此不能在 #DEFINE 中定义。

内核将运行多次(大约 65K),它需要这些参数(和一些其他输入)来进行数学运算。

我的问题是:将这些常量传递给内核的最快(或者最优雅)的方式是什么?

常量是 2 或 3 个元素长度的 float*int* 数组。它们将是其中的 5~10 个。


玩具示例:2个常量const1const2

__global__ void kernelToyExample(int inputdata, ?????){
        value=inputdata*const1[0]+const2[1]/const1[2];
}

是不是更好

__global__ void kernelToyExample(int inputdata, float* const1, float* const2){
        value=inputdata*const1[0]+const2[1]/const1[2];
}

__global__ void kernelToyExample(int inputdata, float const1x, float const1y, float const1z, float const2x, float const2y){
        value=inputdata*const1x+const2y/const1z;
}

或者也许在一些全局只读内存中声明它们并让内核从那里读取?如果是这样,L1,L2,全球?哪一个?

有没有更好的方法我不知道?

在 Tesla K40 上运行。

【问题讨论】:

  • 我在某处读到,您应该按值传递内置类型以获得最佳效率。
  • @StraightLine 很有趣。有什么来源吗?我猜对于一般的变量,但是这一堆不变的呢?能否将它们放在快速存取存储器中的某个位置,并具有比实际发送 65K 副本更好的性能?
  • 一些优化取决于您设备的计算能力。您可以利用 64KB 的常量内存。您还可以将所有常量值排列在一个数组中,并告诉编译器该内存空间将保持不变。

标签: c++ cuda


【解决方案1】:

只需按值传递它们。编译器会自动将它们放在最佳位置,以促进缓存广播到每个块中的所有线程 - 计算能力 1.x 设备中的共享内存,或计算能力 >= 2.0 设备中的常量内存/常量缓存。

例如,如果您有很长的参数列表要传递给内核,那么按值传递的结构是一种简洁的方法:

struct arglist {
    float magicfloat_1;
    float magicfloat_2;
    //......
    float magicfloat_19;
    int magicint1;
    //......
};

__global__ void kernel(...., const arglist args)
{
    // you get the idea
}

[标准免责声明:用浏览器编写,不是真实代码,警告购买者]

如果你的magicint 中的一个实际上只取了你事先知道的少数几个值中的一个,那么模板是一个非常强大的工具:

template<int magiconstant1>
__global__ void kernel(....)
{
    for(int i=0; i < magconstant1; ++i) {
       // .....
    }
}

template kernel<3>(....);
template kernel<4>(....);
template kernel<5>(....);

编译器足够聪明,可以识别magconstant,在编译时知道循环行程,并会自动为您展开循环。模板是一个 very powerful technique 用于构建快速、灵活的代码库,如果您还没有这样做,建议您先熟悉它。

【讨论】:

  • 我在相当不错的 Tesla 40K GPU 上运行。所以你觉得将大约 20 个输入参数作为int const1x 传递给内核会更好吗?而不是“强制”GPU使用特定的内存? (如果你能做到这一点)。
  • 我不会按值传递四十个标量,我会按值将它们传递到结构体中,但是是的,编译器最清楚,没有更好的方法可以做到这一点。实际上,对于可能具有有限值范围的整数常量,有一种更好的方法 - 使它们成为模板参数并实例化不同的内核版本。当常量在编译时已知时,编译器会做很多有用的优化
  • 哇,谢谢! (智能编译器)。您能否(您不介意)添加几个链接或代码 sn-ps,说明如何按值传递结构或制作模板?道歉,还在学习,一切都感觉有点不知所措。
  • @AnderBiguri:我对一些粗略的示例进行了编辑,可能会让您入门。这是我能做的最好的了。
  • 其实很好。非常感谢,非常感谢您的努力!继续做好工作
猜你喜欢
  • 1970-01-01
  • 2014-09-17
  • 2016-04-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-09
  • 1970-01-01
  • 2013-01-29
相关资源
最近更新 更多