CS 758: 多核处理器编程 (2013 年秋季 1 组)

GPU: 10/30

您应该独自完成此作业。不接受逾期作业。

作业文件列表:

本作业的目的是让您熟悉 GPGPU 计算平台 (CUDA) 并获得 GPGPU 特定优化的经验。对于此作业,您将获得在 GPU 上运行的算法的基本实现,并且您将通过应用 GPGPU 优化原则程序性地改进它。

重要提示: CUDA 可能很棘手,特别是如果您犯了错误。错误消息通常很隐晦且信息量不大。尽早开始这项作业!如果您遇到任何问题,请在电子邮件列表上发帖。

问题

对于此作业,您将再次实现 Ocean 算法。您将比较您的 GPU 优化算法的性能与您在作业 1 中的解决方案。模板文件中也包含作业 1 的简单解决方案,如果您愿意,可以随意使用它。

硬件

您将使用 Euler 集群。您应该拥有或即将收到一封包含用户名和临时密码的电子邮件。(确保您重置密码!)阅读上面描述硬件配置的教程。

作业提交

此作业最初设置为将作业提交到 Torque 队列。 对于此作业,请直接在 euler01 上运行作业。

开始:

local $ ssh user@euler.wacc.wisc.edu
euler $ ssh euler01
euler01 $ scp <username>@ale-01.cs.wisc.edu:/p/course/cs758-david/public/html/Fall2013/handouts/homeworks/hw6-dist.tgz .
euler01 $ tar -x -f hw6-dist.tgz
euler01 $ mv hw4-dist hw6
euler01 $ cd hw6
euler01 $ make
euler01 $ ./serial_ocean.sh

只要您的代码快速完成并且您不长时间打开 cuda-gdb,您就不会遇到任何问题(他们遇到过一些 cuda-gdb 有时会阻止访问所有其他 GPU 的错误)。

Euler 集群中提供的硬件信息可在 此处 获得。您将使用 Fermi 卡之一(Tesla 2070/2050 或 GTX 480)。每一个都有 448 个 CUDA 核心(14 个 SM)。

随 CUDA 5.5 一起分发的是一个名为 computeprof 的应用程序,它可以很好地简洁地表示 NVidia GPU 上可用的性能计数器。要使用此程序,您需要使用 @@ssh -X@@ 登录 Euler 集群以转发 X 服务器。然后您可以使用 @@/usr/local/cuda/5.5.22/cuda/bin/computeprof@@ 运行它。我建议在校园里这样做,因为那里的带宽要高得多。您可以使用 computeprof 来诊断算法的每个实现的瓶颈。

附加信息

Dan Negrut 目前正在教授 GPU 计算课程 (ME964)。如果您需要作业的其他信息,您可以在他的课程网页上找到您需要的内容:http://sbel.wisc.edu/Courses/ME964/2013/ 还有一个论坛,班上的学生可以在那里发布问题/答案。它在这里: http://sbel.wisc.edu/Forum/viewforum.php?f=15

步骤 1:移植 CPU 算法

我已在 模板文件 中包含了 @@ocean_kernel@@ 的此实现。您可以在 cuda_ocean_kernels.cu 中的 @@#ifdef VERSION1@@ 之后找到它。虽然更加冗长,但这主要是 omp_ocean.c 中算法的字面翻译,采用 OpenMP 静态分区。每个线程获取红/黑海洋网格内的一块位置并更新这些位置。研究此代码并确保了解其工作原理。

步骤 2:减少内存分歧(将算法转换为 “SIMD”)

实现 @@ocean_kernel@@@@VERSION2@@。此版本的内核将朝着减少内存分歧迈出一步。与其给每个线程一大块数组来处理,不如重写算法,使每个块中的线程处理相邻的元素。(即对于红色迭代,线程 0 将处理元素 0,线程 1 将处理元素 2,线程 3 将处理元素 6,等等)。

步骤 3:进一步减少内存分歧(修改数据结构以使其以 GPU 为中心)。

实现 @@ocean_kernel@@@@VERSION3@@。与其使用一个平面数组来表示海洋网格,不如将其拆分为两个数组,一个用于红色单元格,一个用于黑色单元格。您应该首先编写另外两个内核,将网格对象拆分为 red_grid 和 black_grid,并将 red/black_grid 放回网格对象中。

如果您想冒险,请随时为此实现添加任何其他优化。只需在您的报告中描述它们即可。

提示与技巧

提交内容

请在讲座开始时以 纸质 形式提交此作业。您必须包括: