当您在WebGL或CUDA中编写着色器等时,该代码实际如何转换为GPU指令?
我想学习如何编写超低级代码,将图形渲染优化到极致,以便在硬件/软件边界确切了解GPU指令的执行方式。
据我所知,对于CUDA,您可以购买他们的显卡(GPU),以某种方式实现优化图形操作。但那么你如何编程(在一般意义上),没有C?
这个问题的原因是因为在previous question上,我感觉你不能通过汇编直接编程GPU,所以我有点困惑。
如果你看一下像CUDA by example这样的文档,这些只是C代码(尽管它们有cudaMalloc
和cudaFree
这样的内容,我不会这样做知道在幕后做了什么。但引擎,C必须被编译成汇编或至少是机器代码或其他东西,对吗?如果是这样,那么访问GPU会怎样?
基本上我没有看到在C或GLSL以下的水平如何指示GPU本身如何执行操作。你能解释一下吗?是否有一些装配片段演示它是如何工作的,或类似的东西?或者是否有另一组某种" GPU寄存器"除了16" CPU寄存器"例如在x86上?
答案 0 :(得分:3)
这些语言通过编译器转换为机器代码。该编译器只是各种API的驱动程序/运行时的一部分,并且完全是特定于实现的。在CPU领域,我们习惯没有常见的指令集系列 - 比如x86,arm或者其他什么。不同的GPU都有自己的不兼容的 insruction集。此外,没有用于在这些GPU上上传和运行任意二进制文件的API。根据供应商的不同,几乎没有公开的文档。
这个问题的原因是因为在之前的问题上,我觉得你不能通过汇编直接编程GPU,所以我有点困惑。
嗯,你可以。从理论上讲,至少。如果您不关心您的代码只能在一小部分ASIC上工作,并且您拥有所有必要的文档,并且您愿意为GPU实现一些允许运行这些二进制文件的接口,你能行的。如果你想走那条路,你可以看一下Mesa3D project,因为它为许多GPU提供了开源驱动程序,包括一个基于llvm的编译器基础设施来生成特定体系结构的二进制文件。
在实践中,没有大规模的裸机 GPU编程的有用方法。
答案 1 :(得分:2)
GPU驱动程序将其编译为GPU理解的东西,这完全不同于x86机器代码。例如,这是一个AMD R600汇编代码片段:
00 ALU: ADDR(32) CNT(4) KCACHE0(CB0:0-15)
0 x: MUL R0.x, KC0[0].x, KC0[1].x
y: MUL R0.y, KC0[0].y, KC0[1].y
1 z: MUL R0.z, KC0[0].z, KC0[1].z
w: MUL R0.w, KC0[0].w, KC0[1].w
01 EXP_DONE: PIX0, R0
END_OF_PROGRAM
GPU的机器代码版本将由GPU执行。驱动程序协调将代码传输到GPU并指示它运行它。这些都是非常特定于设备的,在nvidia的情况下,没有文档(至少没有正式记录)。
该代码段中的R0
是一个寄存器,但在GPU上,寄存器的工作方式通常有所不同。它们以“每个线程”存在,并且在某种程度上是共享资源(在某种意义上说,在线程中使用许多寄存器意味着同时有更少的线程处于活动状态)。为了让多个线程同时处于活动状态(这是GPU如何容忍内存延迟,而CPU使用乱序执行和大缓存),GPU通常有数万个寄存器。