YouTube

Got a YouTube account?

New: enable viewer-created translations and captions on your YouTube channel!

Chinese, Simplified subtitles

← cs344_unit5_47_l_总结

Get Embed Code
2 Languages

Showing Revision 5 created 05/20/2013 by Lian7.

  1. 好吧,现在该总结了。这里是我希望你在这个单元所收获的。
  2. 记住APOD —分析、 并行化、 优化和部署。
  3. 这里的要点是在每一步都进行配置文件导引优化,尽早且经常部署,
  4. 而不是在真空中一直优化。我怎么强调这一点都不为过。
  5. 优化需要付出努力而且往往会让代码变得复杂,
  6. 所以只有某个地方、某个时候需要它的时候去优化,多次进行这个循环。
  7. 现在,大多数代码受到内存带宽的限制。
  8. 所以把你的性能与理论峰值带宽相比较,
  9. 如果它表现不佳,看看你能怎么办。
  10. 一些能帮助提升的方法,按照最重要到最不重要的顺序排列:
  11. 保证足够的占有率,确保你有足够的线程以保持机器忙碌。
  12. 这并不意味着机器可以放入多少线程,就要有多少线程,
  13. 但你确实需要足够的线程让机器基本上忙碌。
  14. 合并全局内存存取。
  15. 真的要努力地看看你是否能找到某种方式来构造你的算法,让你能实现完美的合并。
  16. 如果你不能,考虑你是否能进行转置操作,
  17. 或某项操作让你一次得到比较差的合并,
  18. 但是接着把数据放到内存,你对此的所有后续访问将得到很好的合并。
  19. 记住Little法则。
  20. 为了实现最大带宽,
  21. 你可能需要减少你的内存访问之间的延迟时间。
  22. 所以例如,我们看到在第一个例子中,
    我们花太多时间在栅栏处等待。
  23. 通过减少在一个块中的线程数目,
  24. 我们能够减少在栅栏处等待的平均时间,
  25. 并帮助使全局内存带宽饱和。
  26. 我们已经讨论了最小化线程的分支发散。
  27. 请记住这的确适用于在一个warp中发散的线程。
  28. 如果warp自己发散— 换句话说,如果在一个warp内的所有线程都采取同一分支,
  29. 通过相同的代码路径 — 那么就没有代价。
  30. 在不同的warp中的线程发散没有任何额外的代价。
  31. 只有当一个warp内的线程发散,你才必须得在分支的两边执行。
  32. 一般来说,你通常应尽量避免分支过多的代码 —
  33. 代码用了很多if语句,switch语句等等。
  34. 你一般应该考虑避免线程工作负载不平衡。
  35. 换句话说,如果你的内核中有循环,
  36. 可能线程执行次数会有很大差异,
  37. 那么 1个线程会比其它线程平均时间要长,
  38. 这个线程会劫持其余线程作为”人质“。
  39. 以上所说的是,不要让一点点的线程发散吓到你。
  40. 还记得我们分析过一个现实世界的例子,
  41. 处理图像边缘的边界条件,弄清楚实际上if语句
  42. 处理图像边缘不会真正耗费我们很多。
  43. 只有几个warp最终发散。
  44. 如果你受内核实际计算性能限制,
  45. 而不是受到从内核获取或向内核发送数据所需时间的限制,
  46. 那么可以考虑使用快速数学运算。
  47. 这包括像正弦和余弦内部函数等等。
  48. 它们比同类的math.h要快一些,
  49. 代价是几位精度。
  50. 请记住当你使用双精度时,应该是有目的的。
  51. 所以只要逐字键入 3.14,就是一个 64 位双精度数字,
  52. 编译器会把它作为 64 位双精度数字处理,
  53. 而键入 3.14f 告诉编译器,嘿,这是一个单精度操作。
  54. 你不需要提示所有乘以这个或加这个的数字
  55. 是双精度数字。
  56. 最后,如果你受主机设备内存传输时间限制,
  57. 请考虑使用流和异步 memcpys 来重叠计算和内存传输。
  58. 就这样了。现在继续去优化你的代码吧。