> For the complete documentation index, see [llms.txt](https://jizhuoran.gitbook.io/mali-gpu/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jizhuoran.gitbook.io/mali-gpu/mali-gpu-driver/dai-ma-shi-zen-me-dao-gpu-de.md).

# 代码是怎么到GPU的

在开始这一章节之前，决定先聊会儿闲天。作为一个技术文章，上来就讲技术的都是外行，那是代码辅导员，真正好的文章一定是先聊家常，慢慢把你引导~~故事~~内容当中来。我想你在看这本书的时候，也不可能是焚香沐浴，正襟危坐的一页一页翻看。如果真是这样，那绝对是我的失败。在我的期望中，读者都应该左手拿着烤羊腰子，右手拿着啤酒，享受着阅读我这个叨逼叨的玩意儿。有人说不能为了吃活着，真正高尚的人都是为了活着而吃，但我觉得真正的人生应该是且活且吃。

好了，道理我都懂，所以GPU是怎么获取instructions的？其实真正的答案是，我也不知道。真的气啊，找了一天资料，没有一个GPU生产厂家说过这个事儿。我就不明白了，这个东西能算做机密吗？我一气之下就通过driver逆向猜测了一下这个过程，仅仅是写出来~~防止自己忘了~~给大家分享一下。但是要注意两点，一是这个是我喝着啤酒瞎猜出来了，二是这个只是Mali GPU的一个方案。

首先讲一下大约的思路，当用户说要执行一个GPU代码的时候，用户会给driver一个地址，这个地址就指向了这段代码，当然是GPU的机器码。然后driver会把这个地址写到GPU的寄存器上，然后driver会告诉GPU，~~下来接客（差点涉黄啊~~）来任务了，GPU就会通过DMA把这段代码读到一个叫做Job Manager的地方，这个Job Manager是GPU上物理存在的一个东西，而且里面应该有个instruction memory。

当然GPU也不是你让他干啥，他就立马去干啥，在Mali的一个[PPT](http://fileadmin.cs.lth.se/cs/Education/EDAN35/guestLectures/ARM-Mali.pdf)里（真的找的我心累啊）提到过有在硬件眼里有三种jobs，分别是 Vertex Job(V)， Tiler Job(T) 和 Fragment Job(F)。相应的，在driver向GPU提交任务的时候，可以指定一个Job Slots，可能的值是0，1，2。如果你坚信这是一个巧合，那么。。。好吧，你不能认为这是个巧合，这意味着GPU里能同时存分别调度的3种任务，并且这三种任务有自己的priority。

具体到代码上来呢，当一切都准备就绪，压倒GPU的最后一根稻草就是一个叫**kbase\_job\_hw\_submit**的函数。这个函数首先回去看JS\_COMMAND\_NEXT这个寄存器是不是空，如果是，那么机器码的地址的头就会被写进寄存器里。经过一些无聊的操作之后，driver会给这个任务，啪的一声，打上一个时间戳。在设置好很多trace函数之后，driver会写JS\_COMMAND\_NEXT这个寄存器写上一个START，这个任务就进入ALU的汪洋大海当中了。

当然这里我漏掉了一个细节，就是一个job slot到底能放多少个job(s)？很遗憾我现在还不知道，但我知道怎么去知道，所以之后我就会去知道知道。
