TaskPool和Worker的底层模型为Actor模型
Actor并发模型线程之间不共享内存,需要通过线程间通信机制传输并发任务和任务结果
从Volta开始,NV把整数和一些浮点数的pipe分开,使用不同的dispatch port
双发射的第一个指令不能是分支或跳转指令
支持dual-issue
当前CUDA的所有架构都没有乱序执行(Out of order),意味着每个warp的指令一定是按照运行顺序来发射的
在有多个warp满足发射条件的情况下,由于资源有限,需要排队等待发射,warp scheduler会根据一定的策略来选择其中的一个warp进行指令发射
每个指令能否发射还要满足相应的依赖关系和资源需求
有些指令由于功能单元少,需要经由同一个dispatch port发射多次,这样dispatch port是一直占着的,期间也不能发射其他指令
这些功能单元的指令需要通过竞争来获得发射机会
每个指令都要dispatch unit经由dispatch port进行发射
每个指令都需要有对应的功能单元(Functional Unit)来执行
每个Kernel有一个grid,下面有若干个block,每个block有若干个warp。同一个block的warp只能在同一个SM上运行,但是同一SM可以可以容纳来自不同block甚至不同grid的若干个warp
被驳回或通过时
cooperative group
cuda没有解决的是广义DSA指令的掩盖问题,目前主要的workaround是通过给用户暴露warp的概念,并透传指令api的形式解决表达和使用的问题
总的来讲,cuda的成功主要在于解决了两个问题,一个是流水掩盖,一个是指令隐藏
采用内嵌PTX汇编的形式封装好基本的操作,再拼装整个代码的逻辑。这时候已经是在尽量绕开SIMT模型的限制,完全采用DSA的方式组织算子逻辑了
CUDA的成功之处是在于通过SIMT架构掩盖了两件事,一件是上一篇重点讨论的流水编排,另一件是具体的并行指令形式
一般是每个核一个线程,每个线程内串行调用包含各种dsa指令的指令集,这些指令在硬件上通常会dispatch到硬件不同的执行流水线上,正确性有些靠软件插sync实现,有些靠硬件自己保证