既然CPU调用Drawcall是异步的,那么啥情况下CPU会等待GPU
好,前提是 shader 运行的非常慢,CPU 必须等 GPU。(至于 CPU read back data 这种情况就不说了,因为没问。)
【既然CPU调用Drawcall是异步的,那么啥情况下CPU会等待GPU】 在现代的 low-overhead API 里,这个等待不是调用某个 API 的时候 implicitly occur 的,而是靠你自己的代码保证的。以 Metal 为例,需要你创建一个最大等待为 3 的 semaphore,然后在 command encoding 之前要获取(或者等待)这个 semaphore,并且在 command buffer complete 的时候释放它。
为什么是 3 呢?其实也可以是别的数字。这是因为当 CPU 不能确认 GPU 已经完成任务的时候,就不能销毁或者重用为这个任务传递数据用的 buffer(除非确认 buffer 不会发生变化)。所以设成 3 的时候,就需要 3 个(组) buffer,设成 4 的时候,就需要 4 个 buffer。在等待前,提交的任务越多,需要的 buffer 就越多,所以没有必要设的太大。
那么 3 是不是最优呢。现在看来是的。因为 CPU 到 GPU 传递数据的流水线有三步。所以用 3 就可以得到流水线的最大 throughput。
另外一种情况是你在多个 command buffer 之间共享了一个 data buffer,可能因为这个 buffer 太大而且又很少发生变化,所以共享比较有利。那么一旦这个 buffer 真的发生了变化,下一个 command buffer commit 就必须等待上一个完成。(不过讲到这里我有点记不清是需要自己设置同步还是 command buffer commit API 自己就有保证。)
■网友
假设你调的API只有draw跟present,那么会在present等,DX默认CPU只能超过GPU3帧
■网友
等不等看你的程序怎么写,你要是写个glFinish 那CPU 就会等在那里,直到GPU 做完所有工作。
■网友
同步一般都发生在CPU和GPU互相传递数据或信号的时候。比如Occlusion Query之类的。
Present现在也可以不同步了。
■网友
等待发生在cpu和gpu需要同步的时刻,一般都是cpu要访问gpu的一部分resourse,先要maping,但gpu还没画完就要等cmdbuffer里所有cmd执行完才能访问。另外flush,present或者cmd的queue满了,或者cpu要access gpu的结果,都会引发cmdbuffer的submit。如果gpu炒鸡慢,那么cmd ring buffer就会满,runtime会阻塞cpu等待gpu执行cmd这里我是瞎编的,不知道对不对
推荐阅读
- 英雄联盟盒子/大脚为啥要下线换肤功能?
- 关于考研和工作,有些迷茫。
- 既然c程序编译为机器码直接操作硬件,为啥不同操作系统下需要重新编译
- 特斯拉|特斯拉或将允许车主远程调用Autopilot摄像头
- 注销豆瓣之前,有啥简便的备份方法吗
- 既然已有ip追查等确认身份的手段,为啥还要推行网络实名备案
- 苹果为啥不自己设计电脑的CPU?
- webpack打包后的页面,在集成时,怎样提供js接口给父页面调用呢
- 实习辞职了,公司变卦不给工资。各位大神咋办呢
- javascript 中this的四种调用模式
