哪些功能使OpenCL可以在GLSL和GLSL上进行计算,从而成为唯一的选择?尽管图形相关的术语和不切实际的数据类型,OpenGL是否有真正的警告?
例如,可以通过使用其他纹理将a渲染到纹理来完成并行函数评估。缩小操作可以通过迭代渲染越来越小的纹理来完成。另一方面,不可能以任何有效的方式进行随机写访问(唯一的方法是通过纹理驱动的顶点数据渲染三角形)。OpenCL有可能吗?OpenGL无法实现的其他功能?
哪些功能使OpenCL可以在GLSL和GLSL上进行计算,从而成为唯一的选择?尽管图形相关的术语和不切实际的数据类型,OpenGL是否有真正的警告?
例如,可以通过使用其他纹理将a渲染到纹理来完成并行函数评估。缩小操作可以通过迭代渲染越来越小的纹理来完成。另一方面,不可能以任何有效的方式进行随机写访问(唯一的方法是通过纹理驱动的顶点数据渲染三角形)。OpenCL有可能吗?OpenGL无法实现的其他功能?
Answers:
OpenCL专为计算而创建。当您使用OpenGL进行科学计算时,您始终必须考虑如何将计算问题映射到图形上下文(即,就纹理和诸如三角形等的几何图元而言)进行讨论。
在OpenCL中,您只需在内存缓冲区中使用计算内核来制定计算公式,就可以了。这实际上是一个大赢家(从深思熟虑并实现了这两个变体的角度说)。
内存访问模式虽然相同(您的计算仍在GPU上进行-但近来GPU变得越来越灵活)。
但是,除了使用十多个并行“ CPU”而又不打扰如何翻译(例如(愚蠢的例子)将Fourier转换为Triangles和Quads),您还能期望什么呢?
到目前为止,尚未在任何答案中提及的是执行速度。如果您的算法可以用OpenGL图形表示(例如,没有分散的写入,没有本地内存,没有工作组等),则它通常比OpenCL的运行速度更快。我的具体经验是在AMD,nVidia,IMG和Qualcomm GPU上制作图像过滤器(收集)内核。即使经过硬性OpenCL内核优化,OpenGL实现也始终运行得更快。(此外:我怀疑这是由于多年的硬件和驱动程序专门针对基于图形的工作负载进行了调整。)
我的建议是,如果您的计算程序感觉到它很好地映射到图形域,则使用OpenGL。如果不是这样,则OpenCL更通用,更简单地表达计算问题。
值得一提(或询问)的另一点是,您是作为业余爱好者(即为自己)还是商业(即分发给他人)写作。尽管几乎所有地方都支持OpenGL,但OpenCL完全缺乏对移动设备的支持,恕我直言,在未来几年内,极不可能出现在Android或iOS上。如果目标是从单个代码库实现广泛的跨平台兼容性,则可能会强加OpenGL。
哪些功能使OpenCL可以在GLSL和GLSL上进行计算,从而成为唯一的选择?尽管图形相关的术语和不切实际的数据类型,OpenGL是否有真正的警告?
是的:这是图形API。因此,您在其中所做的一切都必须遵循这些条件。您必须将数据打包为某种形式的“渲染”。您必须从属性,统一缓冲区和纹理方面弄清楚如何处理数据。
使用OpenGL 4.3和OpenGL ES 3.1计算着色器,事情变得更加混乱。计算着色器能够以与OpenCL计算操作类似的方式通过SSBO /图像加载/存储访问内存(尽管OpenCL提供实际的指针,而GLSL不提供)。他们与OpenGL的互操作也比OpenCL / GL互操作快得多。
即使这样,计算着色器也不会改变一个事实:OpenCL计算操作的操作精度与OpenGL的计算着色器非常不同。GLSL的浮点精度要求不是很严格,而OpenGL ES的要求甚至更不严格。因此,如果浮点精度对您的计算很重要,则OpenGL将不是计算所需计算量的最有效方法。
此外,OpenGL计算着色器需要支持4.x的硬件,而OpenCL可以在劣等硬件上运行。
此外,如果您通过选择渲染管线进行计算,则OpenGL驱动程序仍将假定您正在渲染。因此,它将基于该假设做出优化决策。假设您正在绘制图片,它将优化着色器资源的分配。
例如,如果要渲染到浮点帧缓冲区,驱动程序可能只是决定为您提供R11_G11_B10帧缓冲区,因为它会检测到您对alpha不做任何事情,并且您的算法可以忍受较低的精度。但是,如果使用图像加载/存储而不是帧缓冲区,则获得此效果的可能性将大大降低。
OpenCL不是图形API。这是一个计算API。
另外,OpenCL仅使您可以访问更多内容。它使您可以访问与GL有关的内存级别。可以在线程之间共享某些内存,但是GL中单独的着色器实例无法直接影响彼此(在Image Load / Store之外,但是OpenCL在无法访问该硬件的硬件上运行)。
OpenGL将硬件隐藏在抽象背后。OpenCL使您几乎完全了解正在发生的事情。
您可以使用OpenGL进行任意计算。但你不希望到; 没有一个完全可行的选择。OpenGL中的计算功能可以为图形管道提供服务。
选择OpenGL进行任何类型的非渲染计算操作的唯一原因是支持无法运行OpenCL的硬件。目前,这包括许多移动硬件。
glTexImage2D
,“ GL将选择一个非常接近internalFormat请求的内部表示,但它可能不完全匹配”。
一个值得注意的功能是分散的写入,另一个可能是缺少“ Windows 7的智能性”。如您所知,如果OpenGL在2秒钟左右不刷新,Windows 7将终止显示驱动程序(不要让我确定确切的时间,但我认为是2秒钟)。如果您进行长时间的操作,这可能会很烦人。
而且,显然,OpenCL不仅可以使用图形卡,还可以使用更多种类的硬件,并且不具有带有“人工约束”的严格的面向图形的管线。同样,运行多个并发命令流也更容易(琐碎)。
shader_image_load_store
)可以解决这一问题,或者您可以使用几何着色器生成其他点或选择不同的输出目标。但是,与OpenCL的灵活性相比,这没有什么比。
尽管目前OpenGL将是图形的更好选择,但这不是永久性的。
OpenGL最终合并为OpenCL的扩展可能是实际的。这两个平台大约有80%相同,但是具有大致相同的语法,但对于大致相同的硬件组件却具有不同的命名法。这意味着要学习两种语言,要弄清楚两种API。图形驱动程序开发人员希望合并,因为他们不再需要为两个单独的平台开发。这为驱动程序调试留下了更多的时间和资源。;)
还要考虑的另一件事是OpenGL和OpenCL的起源是不同的:OpenGL在网络固定管道的早期阶段就开始并获得发展势头,随着技术的发展而逐渐地被附加和弃用。从某种意义上说,OpenCL是OpenGL的发展,因为OpenGL已开始被用于数值处理,因为GPU的(计划外)灵活性允许这样做。“图形与计算”实际上更多是语义论证。在这两种情况下,您始终试图将数学运算映射到具有最高性能的硬件。GPU硬件的某些部分不会使用vanilla CL,但不会保留单独的扩展。
那么OpenGL在CL下如何工作?可以推测,三角形光栅化器可以作为特殊的CL任务入队。特殊的GLSL功能可以在原始OpenCL中实现,然后在内核编译期间由驱动程序覆盖为硬件加速指令。在尚未提供库扩展之前,在OpenCL中编写着色器听起来完全不痛苦。
称一个具有比另一个功能更多的功能并没有多大意义,因为它们都获得了80%的相同功能,只是使用了不同的术语。断言OpenCL不适合图形是因为它是为计算而设计的,这是没有道理的,因为图形处理是在计算。
另一个主要原因是仅图形卡支持OpenGL \ GLSL。尽管多核的使用始于使用图形硬件,但仍有许多硬件供应商致力于针对计算的多核硬件平台。例如,请参阅“英特尔骑士角”。
使用OpenGL \ GLSL开发用于计算的代码将阻止您使用非图形卡的任何硬件。
就OpenGL 4.5而言,以下是OpenCL 2.0具有OpenGL 4.5不具备的功能(据我所知)(这并不涵盖OpenGL具有OpenCL不具备的功能):
大事记
更好的原子
积木
工作组功能:work_group_all和work_group_any work_group_broadcast:work_group_reduce work_group_inclusive / exclusive_scan
从内核入队
指针(尽管如果您在GPU上执行,则可能没有关系)
OpenGL没有的一些数学函数(尽管您可以在OpenGL中自己构造它们)
共享虚拟内存
(更多)内核的编译器选项
轻松选择特定的GPU(或其他方式)
没有GPU时可以在CPU上运行
对那些利基硬件平台(例如FGPA)的更多支持
在某些(所有?)平台上,您不需要窗口(及其上下文绑定)来进行计算。
OpenCL仅允许对计算精度进行更多控制(包括通过这些编译器选项进行的某些控制)。
上面的许多内容主要是为了更好地与CPU和GPU交互:事件,共享虚拟内存,指针(尽管这些也可能使其他内容受益)。
由于这里已经发表了许多其他文章,因此OpenGL获得了将事物分类到客户端和服务器内存的不同区域的能力。OpenGL现在具有更好的内存屏障和原子支持,并允许您将事物分配给GPU中的不同寄存器(与OpenCL可以达到的程度差不多)。例如,您现在可以在OpenGL中共享本地计算组中的寄存器(使用类似AMD GPU LDS(本地数据共享)之类的功能(尽管此特定功能目前仅适用于OpenGL计算着色器)。某些平台(例如Open Source Linux驱动程序)。OpenGL可以使用更多固定功能的硬件(如其他答案所述)。虽然确实可以避免使用固定功能的硬件(例如Crytek使用“软件” 固定功能的硬件可以很好地管理内存(通常比不在GPU硬件公司工作的人要好得多)可以管理内存,并且在大多数情况下要优越得多。我必须承认,OpenCL具有相当不错的固定功能纹理支持,这是主要的OpenGL固定功能领域之一。
我会说英特尔的Knights Corner是一个可自我控制的x86 GPU。我还要指出,具有纹理功能的OpenCL 2.0(实际上是在OpenCL的较小版本中)可以与user2746401建议的性能等级大致相同。
除了已经存在的答案外,OpenCL / CUDA不仅更适合计算领域,而且也不会过多地提取底层硬件。这样,您可以更直接地从诸如共享内存或合并内存访问之类的内容中获利,否则将在着色器的实际实现中埋葬(如果需要,着色器本身仅是特殊的OpenCL / CUDA内核)。
尽管要从这些东西中获利,您还需要更多地了解内核将运行的特定硬件,但是不要尝试使用着色器将这些东西明确考虑在内(即使完全可能)。
一旦您完成了比简单的1级BLAS例程更复杂的操作,您肯定会喜欢OpenCL / CUDA的灵活性和通用性。
varying
为您插入用-keyword声明的顶点数据。您将如何在OpenCL中实现相应的目标?