我是靠谱客的博主 生动丝袜,这篇文章主要介绍double定义的0要写成0.0吗_手把手教你用 Taichi 做高性能并行运算(0),现在分享给大家,希望可以做个参考。

d1c8b796ae3c185ea4275d462598380f.png

最近 GAMES 201 开课了,许多同学对其中 Taichi 编程语言的使用产生了很多疑问。我作为 Taichi 开发者之一,就试着水了一下这篇教程。

性能

众所周知,圆周率是一个常数,约为3.1415926535897,可以用下面这个公式计算:

(对,我故意挑了一个收敛很慢的级数,方便下面进行比较)

写一个Python程序来计算:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import time def calc_pi(): sum = 0.0 for i in range(66666666): n = 2 * i + 1 sum += pow(-1.0, i) / n return sum * 4 t0 = time.time() print('PI =', calc_pi()) t1 = time.time() print(f'{t1 - t0:.3} sec')

运行结果:

复制代码
1
2
PI = 3.1415926385900446 14.5 sec

同样的代码,再试试C语言:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <stdio.h> #include <math.h> #include <time.h> double calc_pi(void) { int i, n; double sum = 0.0; for (i = 0; i < 66666666; i++) { n = 2 * i + 1; sum += pow(-1.0, i) / n; } return sum * 4; } int main(void) { clock_t t0, t1; double pi; t0 = clock(); printf("PI = %.15lfn", calc_pi()); t1 = clock(); printf("%.3f secn", (double)(t1 - t0) / CLOCKS_PER_SEC); return 0; }

运行结果:

复制代码
1
2
PI = 3.141592638590045 1.348 sec

可见,解释型的Python语言,性能上比编译型的C语言差了许多,这是很自然的。

生产力

可是很多时候,同学们更喜欢Python,因为它的拥有面向对象,语法更简洁,还有很多现成的工具包可以使用(比如tensorflow,numpy),大大提升了我们的开发效率。

那么有没有办法,能够将写出的Python代码,高性能地运行呢?

答案是有的,Taichi 就是这样一个包,它会帮你把你的自定义函数编译成机器指令码,在CPU或GPU上并行执行,从而既保证了性能,又保证了生产力。

Taichi 可以通过 pip 安装(需要Python 3.6/3.7/3.8 64位):

复制代码
1
pip install taichi

还是圆周率的例子,要用 Taichi 编译一个函数,以便高性能执行,只需在前面加一个@ti.kernel的装饰器:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import time import taichi as ti @ti.kernel def calc_pi() -> ti.f32: sum = 0.0 for i in range(66666666): n = 2 * i + 1 sum += pow(-1.0, i) / n return sum * 4 t0 = time.time() print('PI =', calc_pi()) t1 = time.time() print(f'{t1 - t0:.3} sec')

运行结果:

复制代码
1
2
3
4
[Taichi] mode=release [Taichi] version 0.6.6, supported archs: [cpu, cuda, opengl], commit 7d76c01c, python 3.8.2 PI = 3.141596794128418 3.62 sec

可见虽然性能不如C语言,还是有很大进步的,毕竟需要动态编译。

Taichi 会默认以 CPU 模式运行,如果指定为 GPU 的话,结果会更快:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import time import taichi as ti ti.init(arch=ti.gpu) # 添加了这行 @ti.kernel def calc_pi() -> ti.f32: sum = 0.0 for i in range(66666666): n = 2 * i + 1 sum += pow(-1.0, i) / n return sum * 4 t0 = time.time() print('PI =', calc_pi()) t1 = time.time() print(f'{t1 - t0:.3} sec')

运行结果:

复制代码
1
2
3
4
[Taichi] mode=release [Taichi] version 0.6.6, supported archs: [cpu, cuda, opengl], commit 7d76c01c, python 3.8.2 PI = 3.1415982246398926 1.56 sec

从以上的例子可以看到,通过 Taichi 的使用,我们可以在 Python 代码里写出接近编译型语言的性能。大大提升了 Python 作为胶水语言的运算能力,特别是大规模并行时的运算能力。

代码分析

@ti.kernel

一切以 @ti.kernel 修饰的函数都会被 Taichi 编译。

def calc_pi() -> ti.f32:

Taichi 是静态类型的,因此需要指定函数的返回类型。

for i in range(66666666):

编译器会自动把 for 循环分配到多个线程,并行执行,线程数量取决于你CPU的核数。而用户完全不必担心 for 循环的展开,编译器会处理一切优化问题。

sum += pow(-1.0, i) / n

Taichi 可以保证+=是原子操作,不会出现多线程数据竞争的问题。

sum = 0.0

这里如果是sum = 0的话,就不行,因为 Taichi 是静态类型的,如果 sum 初始为一个 int,则无法保存接下来数据类型是 float 的 pow(-1.0, i) / n 。编译器将会弹出警告来提醒你这一错误。

可见,虽然代码被传递给了 Taichi 编译器来编译,但大体上依然遵循 Python 的语法。

在下一篇文章中,我将继续介绍 Taichi 的更多特性和应用。

鸣谢

最后,十分感谢 @胡渊鸣 同学和他的开发团队为我们带来了 Taichi 这门高性能并行语言!

最后

以上就是生动丝袜最近收集整理的关于double定义的0要写成0.0吗_手把手教你用 Taichi 做高性能并行运算(0)的全部内容,更多相关double定义的0要写成0.0吗_手把手教你用内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(78)

评论列表共有 0 条评论

立即
投稿
返回
顶部