请在OpenCL内核中查看此代码:
uint point_color = 4278190080;
float point_percent = 1.0f;
float near_pixel_size = (...);
float far_pixel_size = (...);
float delta_pixel_size = far_pixel_size - near_pixel_size;
float3 near = (...);
float3 far = (...);
float3 direction = normalize(far - near);
point_position = (...) + 10;
for (size_t p = 0; p < point_count; p++, position += 4)
{
float3 point = (float3)(point_list[point_position], point_list[point_position + 1], point_list[point_position + 2]);
float projection = dot(point - near, direction);
float3 projected = near + direction * projection;
float rejection_length = distance(point, projected);
float percent = projection / segment_length;
float pixel_size = near_pixel_size + percent * delta_pixel_size;
bool is_candidate = (pixel_size > rejection_length && point_percent > percent);
point_color = (is_candidate ? (uint)point_list[point_position + 3] | 4278190080 : point_color);
point_percent = (is_candidate ? percent : point_percent);
}
此代码尝试在列表中找到最接近远和 near 之间的线段的点,并将其颜色指定给 point_color 及其&#34;百分比距离&#34;进入 point_percent 。 (顺便说一句,代码似乎没问题。)
point_count 指定的元素数量是可变的,所以我不能假设太多,除了一件事: point_count 总是等于或小于8这是我的代码和数据中固定的事实。
我想手动展开这个循环,我担心我需要使用大量的
value = (point_count < constant ? new_value : value)
表示其中的所有行。根据您的经验,这样的策略是否会提高内核的性能?
是的,我知道,我应该自己做一些基准测试;我只想问一下在OpenCL中有很多经验的人,然后自己尝试这个。
答案 0 :(得分:0)
大多数OpenCL驱动程序(至少我很熟悉)支持使用#pragma unroll
在编译时展开循环。只需像这样使用它:
#pragma unroll
for (int i = 0; i < 4; i++) {
/* ... */
}
它实际上与手动展开相同,没有任何努力。在您的情况下,这可能看起来更像:
if (pointCount == 1) {
/* ... */
} else if (pointCount == 2) {
#pragma unroll
for (int i = 0; i < 2; i++) { /* ... */ }
} else if (pointCount == 3) {
#pragma unroll
for (int i = 0; i < 3; i++) { /* ... */ }
}
我无法确定是否会有所改善,但有一种方法可以找到答案。例如,如果pointCount
对于本地工作组来说是不变的,那么它可能会提高性能,但如果它完全可变,这实际上可能会使事情变得更糟。
您可以详细了解here。