OpenGL vs. OpenCL,选择哪个,为什么选择?


78

哪些功能使OpenCL可以在GLSL和GLSL上进行计算,从而成为唯一的选择?尽管图形相关的术语和不切实际的数据类型,OpenGL是否有真正的警告?

例如,可以通过使用其他纹理将a渲染到纹理来完成并行函数评估。缩小操作可以通过迭代渲染越来越小的纹理来完成。另一方面,不可能以任何有效的方式进行随机写访问(唯一的方法是通过纹理驱动的顶点数据渲染三角形)。OpenCL有可能吗?OpenGL无法实现的其他功能?


1
另一个有趣的问题是OpenGL是否可以提供OpenCL无法提供的功能。例如,OpenGL会自动varying为您插入用-keyword声明的顶点数据。您将如何在OpenCL中实现相应的目标?
HelloGoodbye 2014年

我认为,通过为每次调用给计算内核分配一些索引,可以很容易地实现插值。
dronus 2014年

1
我们有2015年,仍然没有在所有平台上都可以可靠地访问OpenCL,仍然好奇OpenCL可以实现什么计算质量,而OpenGL2.0无法实现。
dronus 2015年

1)OpenCL设备可以是cpu,没有任何gpu,并且在图形渲染完全失败的情况下仍可以工作。
xakepp35

2)考虑哪个堆栈更薄,例如在准系统linux内核上?OpenCL仅需要简单的驱动程序,例如amdgpu-pro,随所有必要的lib一起提供(我使用的OpenCL采矿机固件只有50mb的空间)。或渲染器(150 + mb),需要更多的混乱,几个沉重的框架,xorg等,并且诸如在mesa3d / gallium内部完成工作。这是为了什么?如果您的任务仅是计算并且没有运行的x服务器,甚至没有监视器。因此,从根本上说,GL要比CL更“垃圾重载”,以支持多年来开发的所有功能。
xakepp35

Answers:


62

OpenCL专为计算而创建。当您使用OpenGL进行科学计算时,您始终必须考虑如何将计算问题映射到图形上下文(即,就纹理和诸如三角形等的几何图元而言)进行讨论。

在OpenCL中,您只需在内存缓冲区中使用计算内核来制定计算公式,就可以了。这实际上是一个大赢家(从深思熟虑并实现了这两个变体的角度说)。

内存访问模式虽然相同(您的计算仍在GPU上进行-但近来GPU变得越来越灵活)。

但是,除了使用十多个并行“ CPU”而又不打扰如何翻译(例如(愚蠢的例子)将Fourier转换为Triangles和Quads),您还能期望什么呢?


1
傅立叶到三角形和四边形...通过将一个大四边形渲染到纹理上的简单支架,我们就可以将一个或多个大内存块简单地并行映射到另一个。使用不同比例的纹理,也很容易将不同数量(通常为2 ^ n)的值映射到另一个上。那不是太多的GL代码,并且适合大范围的问题。所以我想知道OpenCL可以做什么呢?
dronus 2011年

2
通过使用OpenCL,您完全可以完全省略映射,避免编写应该处理几何图形和片段的着色器,避免考虑坐标的各种转换(世界,屏幕/缓冲区,纹理),并像在您的系统中学到的那样直接表达算法数值类。我对第一个没有问题,但是更喜欢后者。好吧,我最初并没有想到OpenCL的想法-但是像其他人一样,为什么不应该将其用于预期用途?GPGPU暂时很棒,现在只使用OpenCL。
cli_hlt 2011年

7
@ cli_hlt,OpenCL也是GPGPU。
西蒙(Simon)

@Simon从广义上讲,是的,您是对的。但是,根据Wikipedia所说,“图形处理单元(GPGPU,很少使用GPGP或GP²U)上的通用计算是利用图形处理单元(GPU)的,该图形处理单元通常仅处理计算机图形的计算,以在传统上处理的应用程序中执行计算由中央处理器(CPU)”(他们现在省略了其他参考)。使用OpenCL时,不再给出“通常只处理计算机图形的计算”的要点。因此它不是GPGPU的本义。
cli_hlt 2014年

@cli_hlt:也许,但是这些设备仍然主要用于计算机图形。毕竟它们还是被称为GPU!
TimČas16年

53

到目前为止,尚未在任何答案中提及的是执行速度。如果您的算法可以用OpenGL图形表示(例如,没有分散的写入,没有本地内存,没有工作组等),则它通常比OpenCL的运行速度更快。我的具体经验是在AMD,nVidia,IMG和Qualcomm GPU上制作图像过滤器(收集)内核。即使经过硬性OpenCL内核优化,OpenGL实现也始终运行得更快。(此外:我怀疑这是由于多年的硬件和驱动程序专门针对基于图形的工作负载进行了调整。)

我的建议是,如果您的计算程序感觉到它很好地映射到图形域,则使用OpenGL。如果不是这样,则OpenCL更通用,更简单地表达计算问题。

值得一提(或询问)的另一点是,您是作为业余爱好者(即为自己)还是商业(即分发给他人)写作。尽管几乎所有地方都支持OpenGL,但OpenCL完全缺乏对移动设备的支持,恕我直言,在未来几年内,极不可能出现在Android或iOS上。如果目标是从单个代码库实现广泛的跨平台兼容性,则可能会强加OpenGL。


我认为这个答案确实需要更多投票才能在本主题的早期出现。性能考虑因素和移动设备兼容性应首先考虑的关键方面是……至少是性能考虑因素,以防万一您对移动设备不感兴趣(但今天,您怎么能不能,或者更何况您负担不起)? :p)
军舰

OpenGL如何比OpenCL更快?它做得更多,并且管理OpenGL状态的开销很高。您将其与native_ *函数与OpenCL进行了比较吗?您比较了哪种操作?您可以发布代码吗?
Yoav

2
嗨,本乌里。可惜我不能共享代码。您对GL状态相当繁重是正确的,但是编写良好的GL代码通常可以避免状态更改,尤其是对于类似计算的任务(Vulkan在这方面要好得多)。GL / CL之间的单个操作趋于相同,但是GLSL编译器似乎更成熟,并且产生了更严格的代码。同样,对于结构化写入,GL像素着色器可以使用渲染输出单元(ROP),而CL必须使用通用内存子系统(较慢),因为如果写入将被结构化,则通常在编译时无法知道它(通常)。
user2746401

27

哪些功能使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的硬件。目前,这包括许多移动硬件。


6
OpenGL将硬件隐藏在抽象背后。OpenCL使您几乎完全了解正在发生的事情。” 我认为仍然处于抽象水平。GPU具有以OpenGL功能表达的固定模块(例如“渲染输出单元”和“纹理映射单元”)。
dronus

1
@ybungalobill根据的描述glTexImage2D,“ GL将选择一个非常接近internalFormat请求的内部表示,但它可能不完全匹配”。
GuyRT 2014年

1
@GuyRT:它通常为32F提供32F的功能-尽管典型的变化是通道的顺序不同(例如BGRA而不是RGBA)。
TimČas16年

这个答案是指“ OpenGL / GSLS”还是仅指OpenGL?
wotanii

1
@wotanii:GLSL是OpenGL使用的着色语言。因此,没有“仅仅是OpenGL”。
Nicol Bolas

12

一个值得注意的功能是分散的写入,另一个可能是缺少“ Windows 7的智能性”。如您所知,如果OpenGL在2秒钟左右不刷新,Windows 7将终止显示驱动程序(不要让我确定确切的时间,但我认为是2秒钟)。如果您进行长时间的操作,这可能会很烦人。

而且,显然,OpenCL不仅可以使用图形卡,还可以使用更多种类的硬件,并且不具有带有“人工约束”的严格的面向图形的管线。同样,运行多个并发命令流也更容易(琐碎)。


+1代表散射,尽管最近的扩展(如shader_image_load_store)可以解决这一问题,或者您可以使用几何着色器生成其他点或选择不同的输出目标。但是,与OpenCL的灵活性相比,这没有什么比。
Christian Rau

事实是您根本不知道会发生什么,因为一切本质上都取决于驱动程序。当然,如果实现允许的话,您可以执行例如随机内存访问,但是如果事实证明驱动程序只是将整个计算交换到主机,而不是将代码运行在主机上,那么这样做的好处是什么? ...
cli_hlt 2011年

2
@cli_hlt:您可以事先确定任务队列(因此​​是内核)将在什么设备上运行。该实现没有选择权,以后再决定其他事情。同样,诸如分散写入或本地内存之类的功能也不是硬件支持或不支持的“特殊”功能。只是在OpenGL下,相同的硬件不会公开它,因为OpenGL实现了图形管线。这样,在像素着色器中支持写入本地内存根本就没有意义(而“历史”硬件确实无法做到这一点)。在OpenCL中,这是合理的,并且是允许的。
戴蒙

2
(“这根本没有意义”的措词可能有点太苛刻,但是您明白我的意思了。这不是您通常想要的图形,也不是十年前GPU可以做到的。)OpenGL实现“将顶点和连通性信息转换为图像”服务。OpenCL实现“将任意数据转换成其他数据”服务。)
Damon

1
您是否知道,如果OpenCL在GPU上进行冗长的计算,操作系统也会杀死驱动程序?
塔拉

10

尽管目前OpenGL将是图形的更好选择,但这不是永久性的。

OpenGL最终合并为OpenCL的扩展可能是实际的。这两个平台大约有80%相同,但是具有大致相同的语法,但对于大致相同的硬件组件却具有不同的命名法。这意味着要学习两种语言,要弄清楚两种API。图形驱动程序开发人员希望合并,因为他们不再需要为两个单独的平台开发。这为驱动程序调试留下了更多的时间和资源。;)

还要考虑的另一件事是OpenGL和OpenCL的起源是不同的:OpenGL在网络固定管道的早期阶段就开始并获得发展势头,随着技术的发展而逐渐地被附加和弃用。从某种意义上说,OpenCL是OpenGL的发展因为OpenGL已开始被用于数值处理,因为GPU的(计划外)灵活性允许这样做。“图形与计算”实际上更多是语义论证。在这两种情况下,您始终试图将数学运算映射到具有最高性能的硬件。GPU硬件的某些部分不会使用vanilla CL,但不会保留单独的扩展。

那么OpenGL在CL下如何工作?可以推测,三角形光栅化器可以作为特殊的CL任务入队。特殊的GLSL功能可以在原始OpenCL中实现,然后在内核编译期间由驱动程序覆盖为硬件加速指令。在尚未提供库扩展之前,在OpenCL中编写着色器听起来完全不痛苦。

称一个具有比另一个功能更多的功能并没有多大意义,因为它们都获得了80%的相同功能,只是使用了不同的术语。断言OpenCL不适合图形是因为它是为计算而设计的,这是没有道理的,因为图形处理是在计算。


6

另一个主要原因是仅图形卡支持OpenGL \ GLSL。尽管多核的使用始于使用图形硬件,但仍有许多硬件供应商致力于针对计算的多核硬件平台。例如,请参阅“英特尔骑士角”。

使用OpenGL \ GLSL开发用于计算的代码将阻止您使用非图形卡的任何硬件。


我认为OpenCL还会阻止我的代码在当今不是图形卡的任何硬件上高效运行。.因为OpenCL中良好的并行计算与GPU完全匹配,但在当今的普通CPU上却效率很低。
dronus 2011年

4

就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建议的性能等级大致相同。


3

OpenCL(2.0版)描述了异构计算环境,系统的每个组件都可以在其中生成和使用由其他系统组件生成的任务。不再需要更多的CPU,GPU等概念-您只需拥有主机和设备即可。

相反,OpenGL对任务生产者的CPU和任务消费者的GPU进行了严格划分。这还不错,因为更少的灵活性可以确保更高的性能。OpenGL只是更窄范围的工具。


2

除了已经存在的答案外,OpenCL / CUDA不仅更适合计算领域,而且也不会过多地提取底层硬件。这样,您可以更直接地从诸如共享内存或合并内存访问之类的内容中获利,否则将在着色器的实际实现中埋葬(如果需要,着色器本身仅是特殊的OpenCL / CUDA内核)。

尽管要从这些东西中获利,您还需要更多地了解内核将运行的特定硬件,但是不要尝试使用着色器将这些东西明确考虑在内(即使完全可能)。

一旦您完成了比简单的1级BLAS例程更复杂的操作,您肯定会喜欢OpenCL / CUDA的灵活性和通用性。


1
我不确定“但也不会过多地提取底层硬件”。看来OpenCL实际上实际上将完全忽略硬件的某些部分,例如光栅化单元。
dronus 2011年

@dronus好吧,是的,它忽略了固定功能部分。但是另一方面,着色器可以抽象化硬件的多核性质以及诸如不同的内存类型和优化的内存访问之类的东西。
Christian Rau

1
光栅化甚至可以实现某种随机存储器访问(到“三角形连接的”区域...),并保证结果(片段被z深度覆盖)。考虑到内核和内存流,这种行为的仿真将意味着在所有并行线程或其他线程之间使用定义明确的有序互斥量进行随机访问。像这样的并行随机访问可用的OpenCL理念是什么?
dronus 2011年

2

OpenCL的“功能”旨在用于通用计算,而OpenGL则用于图形。您可以在GL中完成任何操作(图灵完成),但是随后您将螺丝刀的手柄当作锤子钉入了钉子中。

另外,OpenCL不仅可以在GPU上运行,而且可以在CPU和各种专用加速器上运行。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.