• 如何并行化普通的python代码


    进程,不会;GIL锁。

    taichi呢?试试吧,也不大会。

    就用这个里面的例子来当靶子

    练一练

    例1

    蒙特卡洛计算pi的代码

    用一行代码实现python多进程加速_哔哩哔哩_bilibili

     

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

    虽然random只取【0,1】,但是也没毛病……比例关系还是一样的。

    python怎么计算时间

    (69条消息) python:计算程序运行时间_Caesar6666的博客-CSDN博客_python计算程序运行时间

    代码

    1. import taichi as ti
    2. import random
    3. import time
    4. ti.init(arch=ti.gpu)
    5. N=1_0000_0000
    6. #对了,蒙特卡洛算Π,用这个来当靶子好了
    7. @ti.kernel
    8. def calc_pai()->ti.f32:
    9. t=0.0
    10. for _ in range(N):
    11. x=ti.random()
    12. y=ti.random()
    13. if x**2+y**2<=1:
    14. t+=1#加锁的
    15. return t/N*4
    16. def calc_pai_normal()->float:
    17. t=0.0
    18. for _ in range(N):
    19. x=random.random()
    20. y=random.random()
    21. if x**2+y**2<=1:
    22. t+=1#加锁的
    23. return t/N*4
    24. start=time.time()
    25. print(calc_pai())
    26. end=time.time()
    27. print("运行时间是",end-start)
    28. start=time.time()
    29. print(calc_pai_normal())
    30. end=time.time()
    31. print("运行时间是",end-start)

    结果 

     如果会写,看来还是有加速的效果的……就怕不会写。

    更复杂的,该怎么做?

    例2

    多文件的怎么搞?哪有那么多单文件的程序?

    首先,python的多文件编程是怎么搞的?

    python多文件编程

    先搞个正常的普通的串行的:

    1. 头文件
    2. /
    3. class calc:
    4. def __init__(self,data_x,data_y) -> None:
    5. self.data_x=data_x
    6. self.data_y=data_y
    7. pass
    8. def calc_pi(self)->float:
    9. t=0
    10. for i in range(len(self.data_x)):
    11. if self.data_x[i]**2+self.data_y[i]**2<=1:
    12. t+=1
    13. return t/len(self.data_x)*4
    14. 主函数
    15. //
    16. import multi_file
    17. import random
    18. import time
    19. N=100_0000
    20. data_x,data_y=[],[]
    21. for i in range(N):
    22. data_x.append(random.random())
    23. data_y.append(random.random())
    24. test=multi_file.calc(data_x,data_y)
    25. start=time.time()
    26. print(test.calc_pi())
    27. end=time.time()
    28. print("运行时间是",end-start,"秒")

     引入taichi

    类+taichi,怎么写的?

    怎么把俩list放到taichi函数里的形参上去?

    列表?ti.field?

    百度启动:(69条消息) 基于python与CUDA的N卡GPU并行程序——taichi语言笔记_遂古之初,谁传道之的博客-CSDN博客_python taichi

    numpy转ti。field?

    也不一定要传吧,搞个全局变量?失败……

    1. import taichi as ti
    2. ti.init(arch=ti.gpu)
    3. DATA_X,DATA_Y=[],[]
    4. @ti.kernel
    5. def calc_pi_parr()->float:
    6. t=0
    7. for i in range(len(DATA_X)):
    8. if DATA_X[i]**2+DATA_Y[i]**2<=1:
    9. t+=1
    10. return t/1000000*4
    11. class calc:
    12. def __init__(self,data_x,data_y) -> None:
    13. self.data_x=data_x
    14. self.data_y=data_y
    15. pass
    16. def calc_pi(self)->float:
    17. t=0
    18. for i in range(len(self.data_x)):
    19. if self.data_x[i]**2+self.data_y[i]**2<=1:
    20. t+=1
    21. return t/len(self.data_x)*4
    22. def calc_pi_2(self)->float:
    23. result=calc_pi_parr()
    24. return result
    25. ///
    26. import multi_file
    27. import random
    28. import time
    29. N=100_0000
    30. data_x,data_y=[],[]
    31. for i in range(N):
    32. data_x.append(random.random())
    33. data_y.append(random.random())
    34. multi_file.DATA_X,multi_file.DATA_Y=data_x,data_y
    35. test=multi_file.calc(data_x,data_y)
    36. start=time.time()
    37. print(test.calc_pi())
    38. end=time.time()
    39. print("运行时间是",end-start,"秒")
    40. start=time.time()
    41. print(test.calc_pi_2())
    42. end=time.time()
    43. 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利用率还高的吓人……这种情况,之前是见过的……可能是因为它要拷贝一个巨大的数组?

    代码记录一下吧,再次失败……

    1. import taichi as ti
    2. ti.init(arch=ti.gpu)
    3. @ti.data_oriented
    4. class calc_parr:
    5. def __init__(self,data_x,data_y) -> None:
    6. #声明
    7. self.DATA_X=ti.field(ti.float32,shape=len(data_x))
    8. self.DATA_Y=ti.field(ti.float32,shape=len(data_y))
    9. #赋值
    10. for index,value in enumerate(data_x):
    11. self.DATA_X[index]=value
    12. for index,value in enumerate(data_y):
    13. self.DATA_Y[index]=value
    14. pass
    15. @ti.kernel
    16. def calc_pi(self)->float:
    17. t=0
    18. for i in range(self.DATA_X.shape[0]):#是方括号不是圆括号不然会报错
    19. if self.DATA_X[i]**2+self.DATA_Y[i]**2<=1:
    20. t+=1
    21. return t/self.DATA_X.shape[0]*4
    22. class calc:
    23. def __init__(self,data_x,data_y) -> None:
    24. self.data_x=data_x
    25. self.data_y=data_y
    26. pass
    27. def calc_pi(self)->float:
    28. t=0
    29. for i in range(len(self.data_x)):
    30. if self.data_x[i]**2+self.data_y[i]**2<=1:
    31. t+=1
    32. return t/len(self.data_x)*4
    33. import multi_file
    34. import random
    35. import time
    36. N=100_0000
    37. data_x,data_y=[],[]
    38. for i in range(N):
    39. data_x.append(random.random())
    40. data_y.append(random.random())
    41. test=multi_file.calc(data_x,data_y)
    42. start=time.time()
    43. print(test.calc_pi())
    44. end=time.time()
    45. print("运行时间是",end-start,"秒")
    46. test=multi_file.calc_parr(data_x,data_y)
    47. start=time.time()
    48. print(test.calc_pi())
    49. end=time.time()
    50. print("运行时间是",end-start,"秒")

  • 相关阅读:
    运用 Elastic Stack 收集 docker 容器日志
    1.5-18:鸡尾酒疗法
    Canal—增量同步数据组件
    牛客 NC25077 [USACO 2007 Ope B]Bronze Cow Party
    社交变革:探索Facebook如何塑造我们的日常生活
    神经网络仿真软件是什么,神经网络仿真软件下载
    竞赛 推荐系统设计与实现 协同过滤推荐算法
    Python3中的for循环
    java计算机毕业设计课题申报系统MyBatis+系统+LW文档+源码+调试部署
    一级造价工程师(安装)- 计量笔记 - 第四章第四节电气照明及动力设备工程
  • 原文地址:https://blog.csdn.net/averagePerson/article/details/127039695