我对英特尔CPU上OpenCL中结构的使用有疑问。我当前的内核使用结构以下列方式访问两个缓冲区:
struct pair {
float first;
float second;
};
inline const float f(const struct pair param) {
return param.first * param.second;
}
inline const struct pair access_func(__global float const * const a, __global float const * const b, const int i) {
struct pair res = {
a[i],
b[i]
};
return res;
}
// slow
__kernel ...(__global float const * const a, __global float const * const b)
{
// ...
x = f( access_func( a, b, i ) );
// ...
}
当我以下列方式更改内核时,它运行得更快:
// fast
__kernel ...(__global float const * const a, __global float const * const b)
{
// ...
x = a[i] * b[ i ];
// ...
}
有没有办法让英特尔编译器进行这种优化? NVIDIA编译器似乎能够做到这一点,因为我没有看到GPU上运行时的差异。
提前致谢!
答案 0 :(得分:0)
编译器无法对数据的内存布局执行优化,考虑到缓冲区在OpenCL设备和主机之间共享,和/或OpenCL设备上的多个内核之间共享;最有效的布局将取决于内核中的访问模式,而且每个内核的访问模式显然都不同。
您需要明智地选择数据的内存布局;这是GPU编程中最难的部分之一。请参阅OpenCL优化指南,了解您所针对的每个实施,以了解他们的偏好。有时,通过从global
内存复制到local
内存,然后从本地副本工作,可以屏蔽低效的访问模式。