Parallel processing 运行并行OpenCL内核

Parallel processing 运行并行OpenCL内核,parallel-processing,opencl,Parallel Processing,Opencl,我已经研究OpenCL有一段时间了,想看看它在我的环境中是否有用。虽然我了解基本知识,但我不确定我是否了解如何强制一个内核的多个实例并行运行 在我的情况下,我想要运行的应用程序本质上是连续的,并且(在某些情况下)需要非常大的输入(数百MB)。但是,所讨论的应用程序有许多不同的选项/标志,可以设置这些选项/标志,在某些情况下会使其更快或更慢。我的希望是,我们可以为OpenCL重新编写应用程序,然后并行执行每个选项/标志,而不是猜测使用哪组标志 我的问题是: 一个图形卡可以并行运行多少内核。这是购买

我已经研究OpenCL有一段时间了,想看看它在我的环境中是否有用。虽然我了解基本知识,但我不确定我是否了解如何强制一个内核的多个实例并行运行

在我的情况下,我想要运行的应用程序本质上是连续的,并且(在某些情况下)需要非常大的输入(数百MB)。但是,所讨论的应用程序有许多不同的选项/标志,可以设置这些选项/标志,在某些情况下会使其更快或更慢。我的希望是,我们可以为OpenCL重新编写应用程序,然后并行执行每个选项/标志,而不是猜测使用哪组标志

我的问题是: 一个图形卡可以并行运行多少内核。这是购买时可以看到的东西吗?它是否与着色器的数量、内存或应用程序/内核的大小相关

此外,虽然应用程序的输入相同,但每次执行都会以不同的方式修改数据。我是否需要将输入数据分别传输到每个内核以实现这一点,或者每个内核是否可以分配“本地”内存

最后,这甚至需要多个内核,我可以使用工作项吗?在这种情况下,如何确定有多少工作项可以并行运行


(参考资料:)

您的问题似乎会不时出现在各种论坛等等。用于在硬件级别上单独运行内核的特性称为设备裂变。阅读更多关于上的扩展,或谷歌“cl_ext_device_Diversitive”

此扩展已在CPU上启用很长时间,但在GPU上未启用。最新的图形硬件可能支持设备裂变。您可能至少需要2014年第2季度或更新版本的GPU,但这将取决于您的研究


让内核只使用OpenCL软件并行运行的方法是在同一设备上使用不同的命令队列对它们进行排队。一些开发人员说多个队列会影响性能,但我个人没有这方面的经验

你的问题似乎不时出现在各种论坛等等。用于在硬件级别上单独运行内核的特性称为设备裂变。阅读更多关于上的扩展,或谷歌“cl_ext_device_Diversitive”

此扩展已在CPU上启用很长时间,但在GPU上未启用。最新的图形硬件可能支持设备裂变。您可能至少需要2014年第2季度或更新版本的GPU,但这将取决于您的研究

让内核只使用OpenCL软件并行运行的方法是在同一设备上使用不同的命令队列对它们进行排队。一些开发人员说多个队列会影响性能,但我个人没有这方面的经验

  • 一个图形卡可以并行运行多少内核
您可以查看一个图形卡上可以并行运行多少内核实例(即,具有不同启动ID的相同内核代码)。这是SIMDs/CUs/shaders/等的一个功能,具体取决于GPU供应商喜欢如何称呼它们。要获得实际执行的内核实例的确切数量有点复杂,因为这取决于占用情况,而占用情况取决于内核使用的资源,例如使用的寄存器、使用的本地内存

如果您是指可以并行运行多少内核调度(即不同的内核代码和cl_内核对象或不同的内核参数),那么我所知道的所有GPU一次只能运行一个内核。这些内核可以从多个命令队列中提取,但GPU一次只能处理一个。这就是为什么当前的GPU不支持cl_ext_device_Splitation的原因-没有办法“拆分”硬件。不过,您可以在内核代码中自己完成(见下文)

  • 每个内核可以分配“本地”内存吗
是的。这正是OpenCL本地内存的用途。但是,它是一种有限的资源,因此应该将其视为内核控制的缓存,而不是堆

  • 在这种情况下,如何确定有多少工作项可以并行运行
与假设内核实例的第一个问题的答案相同

  • 这甚至需要多个内核,我可以使用工作项吗
您可以使用uber内核来模拟运行的不同内核,uber内核根据工作项全局id决定运行哪个子内核。例如:

void subKernel0( .... )
{
    int gid = get_global_id(0);
    // etc.
}

void subKernel1( .... )
{
    int gid = get_global_id(0) - DISPATCH_SIZE_0;
    // etc.
}

__kernel uberKernel( .... )
{
    if( get_global_id(0) < DISPATCH_SIZE_0 )
    {
        subKernel0( .... );
    }
    else if( get_global_id(0) < DISPATCH_SIZE_0 + DISPATCH_SIZE_1 )
    {
        subKernel1( .... );
    }
    else if( .... )
    {
        // etc.
    }
}
void子内核0(…)
{
int gid=获取全局id(0);
//等等。
}
无效子核1(..)
{
int gid=获取全局id(0)-调度大小0;
//等等。
}
__内核(..)
{
if(获取全局id(0)
通常的性能建议使分派大小倍数为32/64等也适用于此处。您还必须调整各种其他ID。

  • 一个图形卡可以并行运行多少内核
您可以查看一个图形卡上可以并行运行多少内核实例(即,具有不同启动ID的相同内核代码)。这是SIMDs/CUs/shaders/等的一个功能,具体取决于GPU供应商喜欢如何称呼它们。要获得实际执行的内核实例的确切数量有点复杂,因为这取决于占用情况,而占用情况取决于内核使用的资源,例如使用的寄存器、使用的本地内存

如果您是指可以并行运行多少内核调度(即不同的内核代码和cl_内核对象或不同的内核参数),那么我所知道的所有GPU一次只能运行一个内核。这些内核可以从多个命令队列中提取,但GPU将只处理