CUDA实践指南(六)

简介:

得到正确答案:
获得正确答案显然是所有计算的主要目标。 在并行系统上,可能会遇到传统的面向串行编程通常不会遇到的困难。 其中包括线程问题,由于计算浮点值的方式而导致的意外值,以及由于CPU和GPU处理器运行方式的不同而带来的挑战。 本章检查可能影响返回数据正确性的问题并指出适当的解决方案。
验证:
参考比较:
对任何现有程序进行修改的正确性验证的关键方面是建立一些机制,从而可以将来自代表性输入的先前已知的良好参考输出与新结果进行比较。 在做出每个更改后,确保结果匹配使用适用于特定算法的任何标准。 有些人会期望逐位相同的结果,这并不总是可能的,特别是在涉及浮点算术的情况下; 有关数字精度的数值精度和精度。 对于其他算法,如果实现在某个小的epsilon中与参考匹配,则可以认为它们是正确的。
请注意,用于验证数值结果的过程也可以轻松扩展以验证性能结果。 我们希望确保我们所做的每一项改变都是正确的,并且改善了性能(以及改善了多少)。 经常检查这些东西是我们周期性APOD过程的一个组成部分,这将有助于确保我们尽快达到预期结果。
单元测试:
上述参考比较的一个有用的对应部分是以这样一种方式构造代码本身,即在单元级别上容易验证。 例如,我们可以将我们的CUDA内核编写为许多简短的__device__函数的集合,而不是一个庞大的单一__global__函数; 每个设备功能都可以独立测试,然后将它们连接在一起。
例如,除了实际的计算之外,许多内核都具有用于访问存储器的复杂寻址逻辑。 如果我们在引入大量计算之前单独验证我们的寻址逻辑,那么这将简化后面的调试工作。 (请注意,CUDA编译器认为任何设备代码都不会将全局内存写入全局内存作为需要消除的死代码,所以我们必须至少将全局内存写入某些内容,以便成功应用我们的寻址逻辑 这个策略。)
更进一步,如果大多数函数被定义为__host__ __device__而不仅仅是__device__函数,那么这些函数可以在CPU和GPU上进行测试,从而增加了我们对函数是正确的信心,并且不会有任何意外 结果的差异。 如果有差异,那么这些差异会很早就看出来,并且可以在一个简单的功能的背景下理解。
作为一种有用的副作用,如果我们希望在应用程序中包含CPU和GPU执行路径,则此策略将允许我们采用一种方法来减少代码重复:如果我们的CUDA内核的大部分工作都在__host__ __device__函数中完成,那么我们 可以轻松地从主机代码和设备代码中调用这些功能而不会重复。

目录
相关文章
|
编解码 并行计算 异构计算
|
并行计算 异构计算 存储
|
存储 并行计算 内存技术
|
并行计算 程序员 异构计算
|
并行计算 Linux
|
并行计算 异构计算 程序员
|
并行计算 大数据 机器学习/深度学习
|
并行计算 Linux Windows