我现在尝试优化我的OpenCL代码。我使用一些指针来返回值。是否更有效地创建存储在寄存器中的临时变量(我猜至少)或者我可以直接访问指针并在整个函数中使用它们,因为它不会对性能产生任何影响,因为编译器会对此进行优化呢?
让我向您展示一个简单的盒子光线交叉的例子:
tmin和tmax存储在临时变量中:
bool intersect(const Ray* ray, float3 boxmin, float3 boxmax, float* tmin, float* tmax)
{
float3 invR = 1.0f / ray->dir;
float t1 = (boxmin.x - ray->origin.x) * invR.x;
float t2 = (boxmax.x - ray->origin.x) * invR.x;
float t3 = (boxmin.y - ray->origin.y) * invR.y;
float t4 = (boxmax.y - ray->origin.y) * invR.y;
float t5 = (boxmin.z - ray->origin.z) * invR.z;
float t6 = (boxmax.z - ray->origin.z) * invR.z;
float tmin_ = fmax(fmax(fmin(t1, t2), fmin(t3, t4)), fmin(t5, t6));
float tmax_ = fmin(fmin(fmax(t1, t2), fmax(t3, t4)), fmax(t5, t6));
if (tmax_ < 0)
return false;
if (tmin_ > tmax_)
return false;
*tmax = tmax_;
*tmin = tmin_;
return true;
}
直接访问:
bool intersect(const Ray* ray, float3 boxmin, float3 boxmax, float* tmin, float* tmax)
{
float3 invR = 1.0f / ray->dir;
float t1 = (boxmin.x - ray->origin.x) * invR.x;
float t2 = (boxmax.x - ray->origin.x) * invR.x;
float t3 = (boxmin.y - ray->origin.y) * invR.y;
float t4 = (boxmax.y - ray->origin.y) * invR.y;
float t5 = (boxmin.z - ray->origin.z) * invR.z;
float t6 = (boxmax.z - ray->origin.z) * invR.z;
*tmin = fmax(fmax(fmin(t1, t2), fmin(t3, t4)), fmin(t5, t6));
*tmax = fmin(fmin(fmax(t1, t2), fmax(t3, t4)), fmax(t5, t6));
if (*tmax < 0)
return false;
if (*tmin > *tmax)
return false;
return true;
}
嗯,这不是最好的例子,因为只有三个解除引用的指针,其中性能可能没有差别,但它只是在那里证明我的意思。 有没有足够深入知识的人,知道大多数OpenCL编译器在这种情况下做了什么? 了解C / C ++编译器在这种情况下会做什么也很有趣。
答案 0 :(得分:1)
取决于您传递的指针的内存位置(tmax
和tmin
)。
性能的最佳解决方案是第一个。您可以在私有空间中执行大部分检查,并且只在需要时访问指向内存的指针。不要担心使用额外的变量,GPU有足够的寄存器:
float tmin_ = fmax(fmax(fmin(t1, t2), fmin(t3, t4)), fmin(t5, t6));
float tmax_ = fmin(fmin(fmax(t1, t2), fmax(t3, t4)), fmax(t5, t6));
if (tmax_ < 0)
return false;
if (tmin_ > tmax_)
return false;
*tmax = tmax_;
*tmin = tmin_;
答案 1 :(得分:0)
这两个选项与任何体面的编译器之间的性能不会有任何差别。大多数OpenCL实现基于llvm,它绝对会优化诸如此类的临时性。
尽管如此,基本上唯一容易辨别的方法是计算两种选择。这始终是优化的证明,但是使用基于CPU的编译器,人们通常也可以查看汇编输出。使用OpenCL更难做到。
注意使用可以使用向量操作使这段代码更简洁。是否有助于表现是另一回事。
你也可以返回一个我认为完全避免使用指针的结构。