opencl - 手动循环展开已知最大尺寸

标签 opencl loop-unrolling

请在 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);
}

此代码尝试在列表中找到距离远近之间线段最近的点,并将其颜色分配给 point_color,并将其“百分比距离”分配给 point_percent。 (顺便说一句,代码似乎没问题)。

point_count 指定的元素数量是可变的,所以我不能假设太多,除了一件事:point_count 将始终等于或小于 8。这是我的代码和数据中的一个固定事实。

我想手动展开这个循环,恐怕我需要使用很多
value = (point_count < constant ? new_value : value)

对于其中的所有行。根据您的经验,这样的策略会提高内核的性能吗?

是的,我知道,我应该自己进行一些基准测试;在我自己实际尝试之前,我只是想问问在 OpenCL 方面有很多经验的人。

最佳答案

大多数 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 .

关于opencl - 手动循环展开已知最大尺寸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49763988/

相关文章:

performance - OpenCL 如何分配工作项?

c++ - 在OpenCL中以编程方式选择最佳GPU的最佳方法是什么?

makefile - 找不到 cl.h - 如何在生成文件中链接

performance - 如果有的话,什么时候循环展开仍然有用?

c++ - 在固定大小的数组上展开 C++ 中的循环是否有用?

使用 gcc 展开循环的正确方法

c - 如果循环的迭代次数在编译时未知,GCC 如何展开循环?

c - 当在一个循环中启动大量内核时,OpenCL 程序会卡住

opencl - 当要处理的元素数量随机增长时,保持固定的 global_work_size 和 local_work_size 是一个坏主意吗?