Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.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
C++ 在OpenCL中使用自己的向量类型似乎更快_C++_C_Opencl_Gpgpu_Vectorization - Fatal编程技术网

C++ 在OpenCL中使用自己的向量类型似乎更快

C++ 在OpenCL中使用自己的向量类型似乎更快,c++,c,opencl,gpgpu,vectorization,C++,C,Opencl,Gpgpu,Vectorization,我在OpenCL中看到了一个smallpt实现,作者在内核中使用了自己的向量类型和前置处理器宏函数 typedef struct { float x, y, z; } Vec; #define vinit(v, a, b, c) { (v).x = a; (v).y = b; (v).z = c; } #define vsmul(v, a, b) { float k = (a); vinit(v, k * (b).x, k * (b).y, k * (b).z) } #define vdot(

我在OpenCL中看到了一个smallpt实现,作者在内核中使用了自己的向量类型和前置处理器宏函数

typedef struct { float x, y, z; } Vec;

#define vinit(v, a, b, c) { (v).x = a; (v).y = b; (v).z = c; }
#define vsmul(v, a, b) { float k = (a); vinit(v, k * (b).x, k * (b).y, k * (b).z) }
#define vdot(a, b) ((a).x * (b).x + (a).y * (b).y + (a).z * (b).z)
#define vnorm(v) { float l = 1.f / sqrt(vdot(v, v)); vsmul(v, l, v); }
and much more...
我测试了代码,并用标准内置float3类型替换了用户定义的向量类型和操作。我很惊讶,作者最初的实现比内置float3的变体快了10帧。之后,我用“英特尔OpenCL应用程序内核生成器”测试了一些情况,似乎证实了内置函数的速度较慢


你知道为什么吗?供应商建议使用内置向量类型:/

用户定义的向量是真正的3元素向量,大小为3个浮点数。 然而,OpenCL
float3
向量实际上使用的是
float4
向量,如
cl\u平台中所示。h

/* cl_float3 is identical in size, alignment and behavior to cl_float4. See section 6.1.5. */
typedef  cl_float4  cl_float3;
最初使用向量是OpenCL推荐的编程技术。因为与普通的非矢量代码相比,利用了完整的SIMD结构

但是随着OpenCL编译器的发展,现在编译器足够聪明,可以在内部对用户代码进行矢量化有时(我在其他内核中也看到过,甚至在我自己的内核中也看到过),最好用普通元素编写代码,让编译器重新对其进行向量化,而不是使用默认的向量类型。因此,我建议,除非向量简化了编程任务并且更易于阅读(例如2D处理等),现在不要使用OpenCL向量

可能用户定义的
vector3
使用的寄存器更少,溢出也更少。也可能是另一种向量排列更适合该算法,并且编译器可以在用户定义的向量情况下自由地重塑代码


必须对编译后的PTX代码进行深入分析。

用户定义的向量是一个真正的3元素向量,大小为3个浮点。 然而,OpenCL
float3
向量实际上使用的是
float4
向量,如
cl\u平台中所示。h

/* cl_float3 is identical in size, alignment and behavior to cl_float4. See section 6.1.5. */
typedef  cl_float4  cl_float3;
最初使用向量是OpenCL推荐的编程技术。因为与普通的非矢量代码相比,利用了完整的SIMD结构

但是随着OpenCL编译器的发展,现在编译器足够聪明,可以在内部对用户代码进行矢量化有时(我在其他内核中也看到过,甚至在我自己的内核中也看到过),最好用普通元素编写代码,让编译器重新对其进行向量化,而不是使用默认的向量类型。因此,我建议,除非向量简化了编程任务并且更易于阅读(例如2D处理等),现在不要使用OpenCL向量

可能用户定义的
vector3
使用的寄存器更少,溢出也更少。也可能是另一种向量排列更适合该算法,并且编译器可以在用户定义的向量情况下自由地重塑代码


必须对编译后的PTX代码进行深入分析。

添加一点。对于NVIDIAGPU(我不知道AMD),有32位(LD.32)、64位(LD.64)和128位(LD.128)的加载指令,但没有96位加载指令。从DRAM加载真正的float3是作为两条独立的指令实现的——一条LD.32指令和一条LD.64指令。如果像对float2、double或float4那样在扭曲中的连续线程中加载连续float3,则实际上是在两条单独的指令中以96位的步幅访问数据,从而导致重放。存储说明也是如此。我猜这就是选择将它们键入float4的原因。

添加一点。对于NVIDIAGPU(我不知道AMD),有32位(LD.32)、64位(LD.64)和128位(LD.128)的加载指令,但没有96位加载指令。从DRAM加载真正的float3是作为两条独立的指令实现的——一条LD.32指令和一条LD.64指令。如果像对float2、double或float4那样在扭曲中的连续线程中加载连续float3,则实际上是在两条单独的指令中以96位的步幅访问数据,从而导致重放。存储说明也是如此。我猜这就是选择将它们键入float4的原因。

这是什么语言?C或C++中没有内置类型<代码> FLUAT3。你的基准代码看起来像什么?这是基于C99标准的OpenCLC,用于GPGPU编程。基准代码只是简单地运行一些基本的向量操作超过一百万次,并将其与用户定义的版本进行比较。(norm、cross、dot、add、mull等)用于基准测试的硬件是Intel i7-3630QM(Intel HD 4000在内核构建器中不起作用)。在我的nvidia quadro gpu(NVS 5200M)上运行的smallpt代码,这是原始的smallpt opencl实现,是使用这些内置类型在CPU上运行的代码,还是在gpu上运行的代码?基准代码是在i7 CPU上运行的,因为Intel的内核构建器中的Intel HD gpu存在缺陷。所有其他代码都运行在英伟达Quero RoC卡上。这是什么语言?C或C++中没有内置类型<代码> FLUAT3。你的基准代码看起来像什么?这是基于C99标准的OpenCLC,用于GPGPU编程。基准代码只是简单地运行一些基本的向量操作超过一百万次,并将其与用户定义的版本进行比较。(norm、cross、dot、add、mull等)用于基准测试的硬件是Intel i7-3630QM(Intel HD 4000在内核构建器中不起作用)。在我的nvidia quadro gpu(NVS 5200M)上运行的smallpt代码,这是最初的smallpt opencl实现,是使用这些内置类型在CPU上运行的代码,还是在gpu上运行的代码?基准代码是在i7 CPU上运行的,因为Intel内核B中的Intel HD gpu存在bug