CUDA实践指南(二十六)

数学库:
中等优先级:每当速度超过精度时使用快速数学库。
支持两种类型的运行时数学运算。 它们可以用它们的名字加以区分:一些名称带有前置下划线,而另一些则没有(例如,__functionName()functionName())。 遵循__functionName()命名约定的函数直接映射到硬件级别。 它们速度更快,但准确度稍低(如__sinf(x)__expf(x))。 functionName()命名约定的函数较慢但具有较高的准确性(例如,sinf(x)和expf(x))。 __sinf(x)__cosf(x)__expf(x)的吞吐量远远大于sinf(x),cosf(x)和expf(x)的吞吐量。 如果参数x的大小需要减小,后者变得更加昂贵(大约慢一个数量级)。 此外,在这种情况下,自变量缩减代码使用本地内存,由于本地内存的高延迟,这会更多地影响性能。 更多详细信息可在CUDA C编程指南中找到.
还要注意,无论何时计算相同参数的正弦和余弦,sincos系列指令都应该用于优化性能:

  • __sincosf()用于单精度快速数学(参见下一段)
  • sincosf()用于常规的单精度
  • sincos()用于双精度

nvcc的-use_fast_math编译器选项强制每个functionName()调用等效的__functionName()调用。 只要准确度优先于性能,就应该使用此开关。 超验函数通常是这种情况。 请注意,此开关仅在单精度浮点上有效。
中等优先:如果可能,优先选择速度更快,更专业化的数学函数,而不是更慢,更一般的数学函数。
对于小整数幂(例如$x^2$或$x^3$),显式乘法几乎肯定比使用pow()等一般指数运算例程更快。 虽然编译器优化改进不断寻求缩小这种差距,但明确的乘法(或使用等效的专用内联函数或宏)可以具有显着的优势。 当需要几个相同基数的幂(例如,其中$x^2$和$x^5$都靠近计算)时,这个优点增加,因为这有助于编译器进行其常见的子表达式消除(CSE)优化。
对于使用基数2或10的指数,使用函数exp2()或expf2()和exp10()或expf10()而不是函数pow()或powf()。 pow()和powf()在寄存器压力和指令计数方面都是重量级的函数,这是由于在大多数幂运算中产生了许多特殊情况,并且难以在整个基数和指数的整个范围内实现良好的精度。 另一方面,函数exp2(),exp2f(),exp10()和exp10f()在性能方面与exp()和expf()类似,并且可以比它们快十倍 pow()/ powf()等价物。
对于指数为1/3的指数,使用cbrt()或cbrtf()函数而不是泛指数函数pow()或powf(),因为前者明显快于后者。 同样,对于指数为-1/3的指数,使用rcbrt()或rcbrtf()。
用sincospi()替换sinpi(),cos(π )与cospi()和sincos(π )的sin(π )。 就精度和性能而言这是有利的。 作为一个特殊的例子,为了评估正弦函数而不是弧度,使用sinpi(x / 180.0)。 类似地,当函数参数的形式为π 时,单精度函数sinpif(),cospif()和sincospif()应该替换对sinf(),cosf()和sincosf()的调用。 (性能优势sinpi()超过sin()是由于简化了参数约简;精确度优势是因为sinpi()仅隐式乘以π,有效地使用无限精确的数学π而不是单精度或双精度逼近。)
精度相关的编译器标志:
默认情况下,nvcc编译器为计算能力2.x的设备生成符合IEEE标准的代码,但它也提供了生成代码的选项,这些代码的精确度稍低但速度更快,并且更接近为早期设备生成的代码:

  • -ftz = true(非规格化数字被刷新为零)
  • -prec-div = false(不太精确的划分)
  • -prec-sqrt = false(不精确的平方根)

另一个更积极的选项是-use_fast_math,它强制每个functionName()调用等效的__functionName()调用。 这使得代码运行速度更快,代价是精度和准确性降低。
内存指令:
高优先级:尽量减少全局内存的使用。 尽可能优先使用共享内存访问。
内存指令包括从共享,本地或全局内存读取或写入的任何指令。 访问未缓存的本地或全局内存时,存在400至600个时钟周期的内存延迟。 例如,以下示例代码中的赋值运算符具有较高的吞吐量,但关键的是,从全局内存中读取数据的延迟时间为400至600个时钟周期:

__shared__ float shared[32];
__device__ float device[32];
shared[threadIdx.x] = device[threadIdx.x];

如果在等待全局内存访问完成时可以发出足够的独立算术指令,那么线程调度程序可以隐藏大部分全局内存延迟。 但是,最好尽可能避免访问全局内存。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: CUDA编程指南8.0中文版本是一份详细的关于基于NVIDIA GPU的CUDA编程的指南。它由NVIDIA公司编写,为初学者以及有经验的CUDA程序员提供了重要的参考和指导。 此指南涵盖了各种主题,包括基础的CUDA编程概念,数据并行性、控制流、共享内存、纹理内存等,并且提供了很多实例代码,从而使读者能够更好地理解这些概念。 在本指南中,读者将学习如何使用CUDA C/C++进行GPU编程,并了解如何构建高性能、高效的GPU应用程序。该指南还介绍了NVIDIA CUDA平台和构建CUDA代码的过程,并提供了许多常用的编程技巧和最佳实践的指导。 其中,8.0版本相较于之前的版本,更充分地考虑了Pascal GPU架构,支持全新的CUDA8.0特性,如无符号整型原子操作、可扩展的每线程等等。 总之,该指南CUDA编程的权威指南,对于想要快速学习CUDA编程以及对GPU加速有兴趣的程序员来说,是一份难得的学习材料。 ### 回答2: CUDA编程指南8.0中文是一本介绍CUDA编程的书籍,由NVIDIA公司出版。CUDA是一种使用GPU进行并行计算的编程模型,可以极大地提高计算效率。本书详细介绍了CUDA编程的基本概念、语法、编程技巧、优化方法等内容,涵盖了从入门到进阶的全系列内容。 本书的前半部分介绍了CUDA编程的基本概念和语法,通过讲解线程、线程块、网格等概念,帮助读者建立起对CUDA编程的直观认识。同时,本书也详细讲解了CUDA的数据类型、内存管理、设备函数、共享内存、纹理内存等重要概念,使读者能够熟练运用这些技术解决实际问题。 本书的后半部分介绍了如何使用CUDA进行优化,包括并行算法、性能分析、调试技巧、内存优化、分布式编程等内容。这些内容对于那些希望将CUDA运用于实际应用中的开发者来说非常有用,能够帮助他们更好地利用GPU的性能优势,提高应用程序的执行效率。 总的来说,CUDA编程指南8.0中文是一本非常实用的CUDA编程教材,是学习CUDA编程必不可少的参考资料。对于那些希望了解CUDA编程并能够自行编写CUDA程序的人来说,这本书绝对是最佳的选择。 ### 回答3: CUDA编程指南8.0中文版是为了帮助开发人员更好地了解CUDA程序设计而编写的一本指南。该指南介绍的主要是基于NVIDIA GPU加速计算的相关知识,目的是让开发人员可以利用GPU提高计算效率、加速计算速度,从而为科学计算和工业应用等领域带来更高的性能和效率。 这本指南包括了CUDA的基础概念,包括线程、块、网格、共享内存、纹理内存、原子操作等,以及CUDA 8.0引入的新功能,如CUDA Runtime API、CUDA Graph、共享内存优化等。此外,指南还通过丰富的代码示例,展示了如何使用CUDA来开发高效的并行计算程序。它还介绍了如何使用CUDA工具来调试和优化CUDA程序,包括CUDA统计分析器、CUDA线程检查器和CUDA延迟检查器等。 除了指南本身外,CUDA编程指南8.0中文版还提供了很多配套资源,包括代码示例、编程工具和CUDA加速库等,这些资源可让开发人员更快地掌握CUDA的编程技巧和应用方法。 总之,CUDA编程指南8.0中文版是一本非常有价值的指南,它提供了丰富的理论和实践知识,帮助开发人员更好地理解和应用CUDA程序设计的能力,从而更好地利用GPU加速计算

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值