在OpenCL中使用自己的Vector类型似乎更快
Using own Vector type in OpenCL seems to be faster
我在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_platform.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编译器的发展,现在该编译器足够聪明,可以在内部对用户代码进行矢量化有时(我也在其他内核中看到过,甚至在我自己的内核中也看到过)最好用纯元素编写代码,并让编译器重新向量化,而不是使用默认的向量类型因此,我建议除非vector简化了编程任务并且更易于阅读(例如2D处理等),否则现在不要使用OpenCL vector。
用户定义的vector3
可能使用的寄存器更少,溢出也更少。或者,另一种矢量排列对算法更好,编译器可以在用户定义的矢量情况下自由地重新塑造代码。
应该使用编译的PTX代码对正在发生的事情进行独立分析。
添加一点。对于NVIDIA GPU(我不知道AMD),有32位(LD.32)、64位(LD.64)和128位(LD.128)的加载指令,但没有96位加载。从DRAM加载一个真正的float3被实现为两个独立的指令——一个LD.32和一个LD.64。如果像对待float2、double或float4那样,在warp中的连续线程中加载连续的float3,那么实际上是在两个独立的指令中以96位的步长访问数据,从而导致回放。存储说明也是如此。我想这就是选择将它们类型定义为float4的原因。
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 推导 std::vector::back() 的返回类型
- 将用户定义的类型与 std::vector 和 std::sort 一起使用
- 在自定义 std::vector-like 容器中处理指针和非指针模板类型的最佳方法是什么?
- C++如何在类Vector中显示不同类型的参数
- 将 std::vector::d ata 传递给函数期望类型**(双指针)
- 如何将 n 个连续元素插入到元素类型不可复制的 std::vector 中?
- 在设计方面:重载vector类型的类成员的插入运算符
- 在从仅移动类型派生的类中定义析构函数在使用 std::vector emplace_back或push_back创建时会
- 如何在OpenCV中存储部分轮廓点喜欢新矢量中的左侧,该类型为<vector<vector<Point>>
- 如何将 Python 对象转换为 Cython 扩展类型的 std::vector 并返回?
- 如何为数据类型 vector<glm::vec3> (opengl 数据类型) 编写 std::minmax 函数的自定义比较器
- 在函数调用中使用类型vector<pair<int,int>>::iterator&in
- 代码不适用于 C++ 中的泛型类型 Vector。<T>
- 错误:无法使用初始值设定项列表初始化非聚合类型 'vector<string>'
- 对于类型"vector<bitset<8>>"c++ 没有可行的重载运算符[]
- 返回类型Vector
- 对持有unique_ptr类型vector的对象列表进行排序
- 错误:无法使用初始值设定项列表初始化非聚合类型 'vector<int>'