进程,不会;GIL锁。
taichi呢?试试吧,也不大会。
就用这个里面的例子来当靶子
练一练
蒙特卡洛计算pi的代码
用一行代码实现python多进程加速_哔哩哔哩_bilibili

原理图,引用自:(69条消息) 蒙特卡洛方法计算圆周率_tiansch的博客-CSDN博客_蒙特卡洛求圆周率

虽然random只取【0,1】,但是也没毛病……比例关系还是一样的。
(69条消息) python:计算程序运行时间_Caesar6666的博客-CSDN博客_python计算程序运行时间
- import taichi as ti
- import random
- import time
- ti.init(arch=ti.gpu)
-
- N=1_0000_0000
-
- #对了,蒙特卡洛算Π,用这个来当靶子好了
-
- @ti.kernel
- def calc_pai()->ti.f32:
- t=0.0
- for _ in range(N):
- x=ti.random()
- y=ti.random()
- if x**2+y**2<=1:
- t+=1#加锁的
- return t/N*4
-
- def calc_pai_normal()->float:
- t=0.0
- for _ in range(N):
- x=random.random()
- y=random.random()
- if x**2+y**2<=1:
- t+=1#加锁的
- return t/N*4
-
- start=time.time()
- print(calc_pai())
- end=time.time()
- print("运行时间是",end-start)
-
- start=time.time()
- print(calc_pai_normal())
- end=time.time()
- print("运行时间是",end-start)

如果会写,看来还是有加速的效果的……就怕不会写。
更复杂的,该怎么做?
多文件的怎么搞?哪有那么多单文件的程序?
首先,python的多文件编程是怎么搞的?
先搞个正常的普通的串行的:
- 头文件
- /
- class calc:
- def __init__(self,data_x,data_y) -> None:
- self.data_x=data_x
- self.data_y=data_y
- pass
- def calc_pi(self)->float:
- t=0
- for i in range(len(self.data_x)):
- if self.data_x[i]**2+self.data_y[i]**2<=1:
- t+=1
- return t/len(self.data_x)*4
-
- 主函数
- //
- import multi_file
- import random
- import time
- N=100_0000
- data_x,data_y=[],[]
- for i in range(N):
- data_x.append(random.random())
- data_y.append(random.random())
-
- test=multi_file.calc(data_x,data_y)
-
- start=time.time()
- print(test.calc_pi())
- end=time.time()
- print("运行时间是",end-start,"秒")

类+taichi,怎么写的?
怎么把俩list放到taichi函数里的形参上去?
列表?ti.field?
百度启动:(69条消息) 基于python与CUDA的N卡GPU并行程序——taichi语言笔记_遂古之初,谁传道之的博客-CSDN博客_python taichi
numpy转ti。field?
也不一定要传吧,搞个全局变量?失败……
-
- import taichi as ti
- ti.init(arch=ti.gpu)
-
- DATA_X,DATA_Y=[],[]
-
- @ti.kernel
- def calc_pi_parr()->float:
- t=0
- for i in range(len(DATA_X)):
- if DATA_X[i]**2+DATA_Y[i]**2<=1:
- t+=1
- return t/1000000*4
-
-
-
- class calc:
- def __init__(self,data_x,data_y) -> None:
- self.data_x=data_x
- self.data_y=data_y
- pass
- def calc_pi(self)->float:
- t=0
- for i in range(len(self.data_x)):
- if self.data_x[i]**2+self.data_y[i]**2<=1:
- t+=1
- return t/len(self.data_x)*4
-
- def calc_pi_2(self)->float:
- result=calc_pi_parr()
- return result
-
-
-
- ///
- import multi_file
- import random
- import time
- N=100_0000
- data_x,data_y=[],[]
- for i in range(N):
- data_x.append(random.random())
- data_y.append(random.random())
-
- multi_file.DATA_X,multi_file.DATA_Y=data_x,data_y
-
-
- test=multi_file.calc(data_x,data_y)
-
- start=time.time()
- print(test.calc_pi())
- end=time.time()
- print("运行时间是",end-start,"秒")
-
- start=time.time()
- print(test.calc_pi_2())
- end=time.time()
- print("运行时间是",end-start,"秒")
这个里面说的——ti.kernel,参数只能是标量,返回值也只能是标量……
所以,就用ti.field,然后用ti.kernel调用ti.func
试试吧……
先声明个field变量,它的形参都是什么意思啊啊?
自带网页,这么高级的吗……

Fields | Taichi Docs (taichi-lang.org)

声明个1D的就行了,那末,怎么给它赋值?
文档里有……

这个ti.field,怎么传参?它好像是个全局变量,不需要传参。
然后,怎么遍历它?

接着找文档……

不好搞,它这个field,大小好像得是提前设置完的。
要不,不是调用taichi函数,而是调用taichi类?
它会把python的变量编译成常量……多次使用的时候搞不好会GG。
代码写成了这样,也可以正常运行了,但是,并行比串行还慢,GPU利用率还高的吓人……这种情况,之前是见过的……可能是因为它要拷贝一个巨大的数组?
代码记录一下吧,再次失败……
-
- import taichi as ti
- ti.init(arch=ti.gpu)
-
- @ti.data_oriented
- class calc_parr:
- def __init__(self,data_x,data_y) -> None:
- #声明
- self.DATA_X=ti.field(ti.float32,shape=len(data_x))
- self.DATA_Y=ti.field(ti.float32,shape=len(data_y))
- #赋值
- for index,value in enumerate(data_x):
- self.DATA_X[index]=value
- for index,value in enumerate(data_y):
- self.DATA_Y[index]=value
- pass
-
- @ti.kernel
- def calc_pi(self)->float:
- t=0
- for i in range(self.DATA_X.shape[0]):#是方括号不是圆括号不然会报错
- if self.DATA_X[i]**2+self.DATA_Y[i]**2<=1:
- t+=1
- return t/self.DATA_X.shape[0]*4
-
-
-
- class calc:
- def __init__(self,data_x,data_y) -> None:
- self.data_x=data_x
- self.data_y=data_y
- pass
- def calc_pi(self)->float:
- t=0
- for i in range(len(self.data_x)):
- if self.data_x[i]**2+self.data_y[i]**2<=1:
- t+=1
- return t/len(self.data_x)*4
-
-
-
- import multi_file
- import random
- import time
- N=100_0000
- data_x,data_y=[],[]
- for i in range(N):
- data_x.append(random.random())
- data_y.append(random.random())
-
-
- test=multi_file.calc(data_x,data_y)
-
- start=time.time()
- print(test.calc_pi())
- end=time.time()
- print("运行时间是",end-start,"秒")
-
- test=multi_file.calc_parr(data_x,data_y)
- start=time.time()
- print(test.calc_pi())
- end=time.time()
- print("运行时间是",end-start,"秒")