YouTube

Got a YouTube account?

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

Chinese, Simplified subtitles

← cs344_unit2_31_l_一个相关问题a

Get Embed Code
2 Languages

Showing Revision 1 created 05/23/2013 by Lian7.

  1. 好的,我们来讨论一个相关问题。
  2. 当你有很多线程读写相同的内存位置,会发生什么?
  3. 如果很多线程都试图读写相同的内存位置,
  4. 那么你会得到冲突。
  5. 我们来看个例子。
  6. 假设你有10000个线程都试图增加10个数组元素。
  7. 会发生什么?
  8. 我们来看些代码。
  9. 这比我们之前在这些例子中看到的更复杂一点,
  10. 让我来简单讲解一遍。
  11. 我要做的是试着用很多线程
  12. 写入少量数组元素。
  13. 在这个例子中,我将用一百万个线程写入十个数组元素,
  14. 我将用一千的线程块进行该操作。
  15. 这是#defines。
  16. 它有个小的帮助函数,输出一个数组。
  17. 我们用这个来调试。
  18. 接着这是我们要用的内核。
  19. 它是内核,因为它被标识为全局。
  20. 它叫做increment_naive,用一个指针到全局内存和一个整数数组。
  21. 每个线程只是通过看块索引,弄清它是什么线程,
  22. 这是哪个块乘以一个块有多少线程,加上它是这个块中的哪个线程。
  23. 现在我们要做的是让每个线程增加
  24. 数组中的一个线程。
  25. 要做这个,我们只要把线程索引除以数组大小取余数。
  26. 每个线程将— 每个连续线程将增加数组中的连续元素,
  27. 围绕着数组大小。
  28. 我们有一百万个线程只写入10个元素的事实意味着
  29. 在每个线程都已对其相应数组元素加一之后,
  30. 我们最终得到的10个元素,每个都含有数字100000。
  31. 代码本身很简单。
  32. 我们有个timer类。
  33. 我再次隐藏了,你现在不需要涉及它。
  34. 我们要声明一些主机内存。
  35. 我们要声明一些GPU内存。
  36. 我们要将内存归零。
  37. 你之前没见过cudaMemset,但它正是你想的。
  38. 我们将把这个设备数组的所有字节设为零。
  39. 现在我们要启动内核。
  40. 我已在这放了个计时器,
  41. 因为我想展示给你看的一点是原子操作会让程序减速。
  42. 这是被我们叫做increment_naive的内核。
  43. 我们将用很多线程块启动它,
  44. 线程块数目等于线程总数除以线程块宽度,
  45. 每个块的线程数等于线程块宽度。
  46. 还记得,这些数最初是1000000和1000,好吗?
  47. 我们最终启动一千个线程块,
  48. 我们将传递设备数组,
  49. 然后每个线程将进行增量。
  50. 当所有都完成了,我们将停止计时器,用cudaMemcpy复制回数组。
  51. 现在,我们取我们刚增加的数组,
  52. 把它复制回主机,然后我隐藏了一个小的print_array帮助函数。
  53. 它打印输出数组的内容。
  54. 然后我将打印输出这个内核所花时间的毫秒数,
  55. 我用一个计时器测得。
  56. 好的。这是整个CUDA程序。我们来编译并运行它