使用vload Vs直接分配向量指针有什么好处吗?移动GPU的速度更快,计算能力更低。带宽?
例: ** vload sample **
__kernel vec_add(__global const float* a, __global const float* b, __global float* c){
float4 a_sub;
float4 b_sub;
float4 c_sub;
a_sub = vload4(0, &a[get_global_id(0)]);
b_sub = vload4(0, &b[get_global_id(0)]);
c_sub = a_sub + b_sub;
vstore(c_sub, 0, &c[get_global_id(0)]);
}
矢量指针示例
__kernel vec_add(__global const float* a, __global const float* b, __global float* c){
float4 a_sub;
float4 b_sub;
float4 c_sub;
a_sub = ((global const float4*)a)[get_global_id(0)];
b_sub = ((global const float4*)b)[get_global_id(0)];;
c_sub = a_sub + b_sub;
vstore(c_sub, 0, &c[get_global_id(0)]);
}
答案 0 :(得分:1)
如评论中所述,它取决于目标硬件,这是加载数据的最快方式。换句话说,你应该确定哪个是最好的或有任何区别。但是,我不记得通过改变语法来实现任何加速。
如果你需要使用float*
缓冲区,那么尝试的第三个选项就是编写相同的加载:
a_sub = (float4){
a[get_global_id(0) * 4 + 0],
a[get_global_id(0) * 4 + 1],
a[get_global_id(0) * 4 + 2],
a[get_global_id(0) * 4 + 3]
};
但是,很多时候没有理由使用float*
缓冲区,您可以使用float4*
个缓冲区。在这种情况下,编译器肯定知道负载将是对齐的。此外,当我更改缓冲区类型时,我已经看到移动平台上的显着加速。所以在你的情况下,内核签名看起来像:
__kernel vec_add(__global const float4* a, __global const float4* b, __global float4* c){
并且负载将是:
a_sub = a[get_global_id(0)];