使用传统的连续缩减方法,下图缩小为:
(+ (+ 1 2) (+ 3 4)) ->
(+ 3 (+ 3 4)) ->
(+ 3 7) ->
10
图形缩减虽然本质上是平行的。相反,人们可以将其减少为:
(+ (+ 1 2) (+ 3 4)) ->
(+ 3 7) ->
10
据我所知,每种函数式编程语言都使用第一种方法。我相信这主要是因为在CPU上,调度线程过度补偿了并行减少的好处。但是,最近,我们开始使用GPU而不是CPU用于并行应用程序。如果一种语言完全在GPU 上运行,那么这些通信费用就会消失。
是否有功能语言利用这个想法?
答案 0 :(得分:10)
是什么让你对GPU调度有所考虑不会过度贡献这些好处?
事实上,GPU中使用的并行性要难以安排:它是SIMD并行性,即一整批流处理器一次完成所有基本相同的事情除了每一个粉碎一堆不同的数字。因此,您不仅需要安排子任务,还需要保持它们同步。为一般计算自动执行此操作几乎是不可能的。
为特定任务执行此操作非常好,并已嵌入到函数式语言中;查看Accelerate project。
答案 1 :(得分:5)
SPOC提供了来自OCaml的一些GPGPU访问权。
答案 2 :(得分:4)
在CPU上,调度线程过度补偿了并行减少的好处
线程调度在现代操作系统中非常有效。线程初始化和终止可能是一个值得关注的问题,但有很多技术可以消除这些成本。
图形缩减虽然本质上是平行的
正如其他答案所述,GPU是非常特殊的设备。人们不能简单地采用任意算法,只需重写CUDA就可以快100倍。说到CUDA,它不是SIMD(多数据上的单指令),而是SIMT(多线程上的单指令)。这是一个复杂得多的东西,但让我们把它看作仅仅是一种矢量处理语言。顾名思义, vector 处理器设计用于处理密集向量和矩阵,即简单的线性数据结构。因此,warp中的任何分支都会降低并行性和性能降低到零的效率。现代建筑(Fermi +)甚至能够处理一些树木,但这相当棘手,性能并不那么闪亮。所以你根本无法加速任意图形缩减。
GPGPU的功能语言怎么样?我相信它不会是严重的。大多数有价值的CUDA代码存在于由博士制作的几乎不优化的库中,并且它直接针对性能。功能语言的可读性,声明性,清晰度甚至安全性并不重要。
答案 3 :(得分:2)
语言Obsidian是嵌入在Haskell中的特定于域的语言,它针对GPGPU计算。它比你要求的更低级,但我想我还是会提到它。
答案 4 :(得分:0)
https://github.com/BenjaminTrapani/FunGPU 提供了一种类似 Racket 的函数式语言,它完全运行在 GPU 和其他可以使用 SYCL 定位的设备上。运行时以有效利用 GPU 的方式自动调度独立的子树(同时评估具有不同数据的相同指令的多个评估)。它仍处于早期阶段,但值得尝试。它已经超过了 Racket VM。