Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Types 从恒定内存均匀加载128位数据_Types_Vector_Cuda_Structure_Gpgpu - Fatal编程技术网

Types 从恒定内存均匀加载128位数据

Types 从恒定内存均匀加载128位数据,types,vector,cuda,structure,gpgpu,Types,Vector,Cuda,Structure,Gpgpu,给定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;} 此外,是否可以直接访问向量类型而不必强制转换它,如下所示:

给定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;}
此外,是否可以直接访问向量类型而不必强制转换它,如下所示:

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:

在第一种情况下,铸造可能是最简单的解决方案,因此如下所示:

__constant__ int constant_mem[4];
__global__ void kernel(){
    int4 vec = * reinterpret_cast<int4 *>(&constant_mem);
}
(在浏览器中编写的免责声明,未经编译或测试,使用风险自负)


在这里,我们通过读取整个
int4
值并解析它们的内容来强制执行128位事务(对void的强制转换是open64编译器旧版本所必需的咒语,如果它认为成员未使用,则倾向于优化向量加载)。编制索引需要一些IOPs开销,但如果生成的事务的负载带宽更高,这些开销可能是值得的。switch语句可能是使用条件执行编译的,因此不应该有分支发散惩罚。请注意,对int4值数组的随机访问可能会浪费大量带宽,并导致扭曲序列化。这样做可能会对性能产生很大的负面影响。

请提供更多信息。“不起作用”是什么意思?显示未定义类型和内存空间的代码段并没有多大帮助。理想情况下,您发布的代码应该简短且完全独立。这使那些可能帮助你的人的工作变得更容易,他们不必在评论中猜测或要求澄清(如在你的最后一个问题中)@Talonmes抱歉,我不清楚,我的意思是说代码不会编译。我已经更新了问题,将编译错误包括在内。我还包括了我试图编译的基本代码。对于第一种情况,听起来您需要类似于
vector=*reinterpret\u cast(&constant\u mem)
的东西,但是为什么不在第二种情况下访问int4中的成员呢?我还遗漏了什么吗?@Talonmes我已经找到了解决第一种情况的方法,将常量内存声明为int4。对于第二种情况,我需要基于线程ID访问数据。因此,我不能简单地使用vector.x、vector.y等来访问它。我可能会将数据转换为int数组,但我不确定这是否安全,它看起来也不是很干净。在我的情况下,对int4值数组的访问不会是随机的。它将通过固定索引进行访问:数组[0]、数组[1]等,因此内存事务不应序列化。我对NVCC生成的PTX文件进行了大量研究,似乎您的开关状态确实生成了分支。我已更新了问题,以包括生成的PTX程序集。然而,我的程序似乎确实有效。它利用了扭曲同步性,所以这些分支没有破坏程序是相当令人困惑的。我警告过你我没有编译它。如果访问不是随机的,并且每个索引在编译时都是已知的,那么考虑将索引参数设为FETCH4模板参数。这将允许编译器优化分支。对常量内存的访问不是随机的,但向量被读入本地内存,在本地内存中,根据线程ID访问一个32位字。我想也许有一种更干净的方法可以做到这一点,但我应该先运行一个概要文件,看看这个新方法与我以前版本的程序相比如何。如果你还感兴趣,我会告诉你最新情况。
__constant__ int constant_mem[4];
__global__ void kernel(){
    int4 vec = * reinterpret_cast<int4 *>(&constant_mem);
}
__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);
}