给定CUDA向量类型int4
,如何从常量内存中加载128位数据。
这似乎不起作用:
#include <stdio.h>
#include <cuda.h>
__constant__ int constant_mem[4];
__global__ void kernel(){
int4 vec;
vec = constant_mem[0];
}
int main(void){return 0;}
在第七行,我试图将常量存储器中的所有4个整数值加载到128位向量类型中。此操作导致以下编译错误:
vectest.cu(7): error: no operator "=" matches these operands
operand types are: int4 = int
此外,是否可以直接访问矢量类型而无需投射它,如下所示:
int data = vec[0];
PTX程序集中的切换语句:
@%p1 bra BB1_55;
setp.eq.s32 %p26, %r1, 1;
@%p26 bra BB1_54;
setp.eq.s32 %p27, %r1, 2;
@%p27 bra BB1_53;
setp.ne.s32 %p28, %r1, 3;
@%p28 bra BB1_55;
mov.u32 %r961, %r61;
bra.uni BB1_56;
BB1_53:
mov.u32 %r961, %r60;
bra.uni BB1_56;
BB1_54:
mov.u32 %r961, %r59;
bra.uni BB1_56;
BB1_55:
mov.u32 %r961, %r58;
BB1_56:
答案 0 :(得分:1)
在第一种情况下,施法可能是最简单的解决方案,所以像这样:
__constant__ int constant_mem[4];
__global__ void kernel(){
int4 vec = * reinterpret_cast<int4 *>(&constant_mem);
}
(免责声明用浏览器编写,未编译或测试,使用风险自负)
使用C ++ reinterpret_cast
运算符将强制编译器发出128位加载指令。
在第二种情况下,听起来你想使用128位内存事务直接寻址存储在128位向量类型数组中的32位字。这需要一些辅助函数,可能类似于:
__inline__ __device__ int fetch4(const int4 val, const int n)
{
(void) val.x; (void) val.y; (void) val.z; (void) val.w;
switch(n) {
case 3:
return val.w;
case 2:
return val.z;
case 1:
return val.y;
case 0:
default:
return val.x;
}
}
__device__ int index4(const int4 * array, const int n)
{
int div = n / 4;
int mod = n - (div * 4);
int4 val = array[div]; // 128 bit load here
return fetch4(val, mod);
}
__constant__ int constant_mem[128];
__global__ void kernel(){
int val = index4(constant_mem, threadIdx.x);
}
(免责声明用浏览器编写,未编译或测试,使用风险自负)
这里我们通过读取整个int4
值并解析它们的内容来强制执行128位事务(转换为void是open64编译器的旧版本所必需的咒语,如果它认为成员的话,它很容易优化矢量加载没用了)。有一些IOP的开销来进行索引,但如果生成的事务的负载带宽更高,它们可能是值得的。 switch语句可能是使用条件执行编译的,因此不应该存在分支差异惩罚。请注意,对int4值数组的随机访问可能会浪费大量带宽并导致warp序列化。这样做可能会对性能产生很大的负面影响。