从GPU的角度看job的完成

今天已经是腊月二十八了,开车走在路上就像十年前一样畅通无阻,想必是要过年了。今天在朋友圈看到很多山东人回家指南,里面有不少对山东酒文化的讨论。作为一个非典型山东城市的人,其实我对于这些山东酒文化是没有调查就没有多少发言权的。权且把这些朋友圈的言论当作事实,来比较一下山东其他的确和青岛过年喝酒的特点。

首先最大的区别就是,在青岛是允许喝除了白酒之外的酒的。作为啤酒之都(这个各有看法吧,你当然不能拿工业化生产的拉格和费尽心思生产的艾尔比。个人感觉无论是三四块钱的尿啤还是十几块钱的原浆,青岛啤酒的水平都是说的过去的),即使是在过年,青岛也会允许你喝啤酒,只要你按照一定的比例。但是如果别人直接跟你说啤酒和白酒应该1:4或者1:6,并为此大为辩论的,那么他一般不是一个青岛人。因为在青岛,这个比例是有所变化的,其实这个是非常讲理的,在夏天和在冬天喝啤酒的感觉是极为不一样的。在夏天,太阳落山之后,即使是在室外也不会感觉到炎热,这时吃着烧烤,吹着牛B,人家喝一瓶低度白酒你就要喝六瓶啤酒。而在过年期间,即使是在温暖的室内,啤酒的威力也会在人们的心中被放大,这个时候我们只需要拿五瓶啤酒就能顶得上一斤低度白酒了。这里我们特地强调了低度白酒,因为如果有人喝高度白酒,就说明这真是个喝主儿,一般也就不会计较这些比例了。

其次呢,劝酒在青岛基本是不怎么存在的。喝酒无外乎就两种情况,第一是和亲朋好友们一起喝酒,大家都知道你的酒量,这时候如果你还要别人劝,那就有点不够意思了。第二种情况就是和不太熟的人一起喝酒,这个时候其实劝酒是有极大风险的,因为可能确实对方只有一杯白酒的酒量,如果真的碍于面子被强劝几杯,那么很有可能要出问题。本来是一件开心的事儿,如果一不小心变成了悲剧,那么年也不怎么好过了。

最后呢,就是讲一点全国,乃至全世界都相同的道理吧。以酒会友交天下朋友,用心处事结四海豪杰。

其实,刚才不能是最后,还是得书归正传,讲点干货。

kbase_gpu_complete_hw这个函数里呢,首先会处理和ISSUE有关的问题,然后再真正的处理完成的jobs。

在有TMIX_8438这个ISSUE的时候,如果一个hard stop紧接着一个soft stop产生,那么这个hard stop的停止代码可能被设置成了STOP,虽然他真是应该是TERMINATED。

如果当前GPU有ISSUE 6787,并且BASE_JD_REQ_SKIP_CACHE_END被设置了,那么对于失败的job chain,GPU的cache不会被刷出来。为了防止之后eviction造成存储的破坏,我们需要把缓存里的内容刷出来。如果GPU有ISSUE 10676,也需要进行如上操作,只不过判断条件稍有不同。

在处理完和ISSUE相关的事宜后,我们就把这个atom从JS中dequeue出来,说白了就是把他的状态设置成NOT_IN_SLOT。

如果当前的complete_code是STOPPED,那么我们就需要按需来把ringbuffer中的下一个atom从中dequeue掉。这个atom应该已经被从GPU中的NEXT寄存器中remove掉了,这个过程是在kbase_gpu_soft_hard_stop_slot完成的。我们检测是否有next_atom,这个atom是否跟当前的atom属于同一个kctx并且priority相等。如果上述条件都满足,那么我们就会dequeue掉这个next atom并且把他送还到JS里。

对于剩下的complete_code,如果不是DONE,那么就执行相同的操作。我们首先先禁止当前atom所对应的context再向device递交任何job。然后我们会把这个context的所有有dependency的job,不论是在哪个job slots里的,都从JM里dequeue出来。当然,已经被submit到GPU的不会被移除,因为但凡他们被提交到GPU上,就证明他们没有dependency的问题。

在处理完以上的情况之后,所有的分支都会被归并到一段代码,就是说之后的代码是所有的进入这个函数的完成了的atom都会执行的。如果这个atom的job_tail不是0或者katom->jc,那么就说明他没有执行完,我们就需要把katom->jc指向现在的tail,这样之后resume的时候,就能从正确的地方开始。随后,我们把complete_code储存到katom的结构体里,除非是CANCELLED。

如果complete_code是STOPPED,那么就要把这个katom还给JS,否则都视为完成并调用kbase_jm_complete。而且因为当前的katom完成了,那么有一些cross-slot的dependency可能被解决了,我们就可以试着去提交当前katom的slot上job。

最后,这个job的完成可能会unblock其他atom,我们调用kbase_backend_slot_update去更新slot上job的的状态(之前介绍过这个函数)。