两项任务

  正在干活儿的时候,收到了老板的消息弹窗,他让我暂时停下手上的其他工作,有两个优先级更高的新任务给我。

第一项任务🤔

  第一项任务是需要将一个旧的单精度kernel改造为新的使用双精度计算的kernel。
  先给kernel来个体检看看,其他指标没啥看头,看看roofline吧:
singleUpline
  矮的那一根横线是FP64的上限,橘红色的点就是当前值。看了代码也觉得问题不大,主要就是注意一下share memory的使用,防止bank conflict,以及全局内存的合并访问,都是常规操作了,仔细一点就行。改完再跑一下测试看看:
DoubleGood
  橘色的点已经贴近它的上限了😄,按理论上的计算峰值来看,最多还能提升40%,然而先不说这理论上40%的提升能不能在现实生产环境中实现,就算真能实现,估计消耗的时间成本会增加800%。领导以前在英伟达搞cuda,经常搞sass,估计他能演示一下什么是极致的性能优化,我目前是不会sass优化的😂。

第二项任务🤔

  第二项任务,是要把一个小模块的执行时间尽量压缩到100ms以内,该模块以前用在问题规模较大的场景,现在想在问题规模小的场景下使用,所以需要调整一下。
too_much_stream_and_event
  结合上图和实际代码,不难看出原来的方案使用了太多的stream。
GPU_Throughput_good
  从上图看出访存有些问题,需要配合问题规模的缩减而作适当调整。既然问题规模缩小了,那么合并部分stream,再看看哪一些地方能用线程同步来减少流同步的使用,估计就能达标了。
  改了测,测了改,折腾了好几遍,最后调出个性能不错的,再跑个测试看看:
Double_Precision
  感觉可以了,再用event看看耗时:
time_used
  到100ms以内了,OK!😁

总结😋

  写了一段时间cuda,感觉自己就像一个老中医一样,手里拿着一堆检测工具,对着代码望闻问切。整个cuda代码优化的过程,经常会出现按下葫芦起了瓢的情况,比如你想着多用share memory,它速度快,但是用太多又会导致SM上面驻留的warp数量下降,真就是“螺蛳壳里做道场”的感觉😂。