当前位置: 首页 > news >正文

如何并行化普通的python代码

进程,不会;GIL锁。

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

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

练一练

例1

蒙特卡洛计算pi的代码

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

 

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

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

python怎么计算时间

(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)

结果 

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

更复杂的,该怎么做?

例2

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

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

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

类+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,"秒")

相关文章:

  • 人力资源团队怎样利用智能科技提升工作效率
  • 对角线的输出
  • Charles乱码和SSL 代理问题解决
  • SharedPreference使用
  • Javaweb安全——Shiro漏洞利用
  • java基本微信小程序的高校科研管理系统 uniapp小程序
  • C++ 20 协程(一)
  • 小米手机抓取hci log
  • 【Java深入学习】并发常见方法的注意事项
  • 微信小程序开发入门与实战(数据监听)
  • 【论文阅读】提升的自动作文评分通过Prompt预测和匹配
  • JPA-Specification常用条件查询构造方式
  • 瑞吉外卖(19) - 新增套餐业务开发
  • Android 的定位分层架构
  • 基于docker搭建es集群
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • 【知识碎片】第三方登录弹窗效果
  • 5、React组件事件详解
  • ES6系列(二)变量的解构赋值
  • FineReport中如何实现自动滚屏效果
  • jdbc就是这么简单
  • vue-cli3搭建项目
  • 阿里云应用高可用服务公测发布
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 官方解决所有 npm 全局安装权限问题
  • 后端_MYSQL
  • 计算机常识 - 收藏集 - 掘金
  • 简单数学运算程序(不定期更新)
  • 京东美团研发面经
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 利用DataURL技术在网页上显示图片
  • 每天一个设计模式之命令模式
  • 手机端车牌号码键盘的vue组件
  • 问:在指定的JSON数据中(最外层是数组)根据指定条件拿到匹配到的结果
  • 我的面试准备过程--容器(更新中)
  • 《天龙八部3D》Unity技术方案揭秘
  • 1.Ext JS 建立web开发工程
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • ​​快速排序(四)——挖坑法,前后指针法与非递归
  • # Maven错误Error executing Maven
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (保姆级教程)Mysql中索引、触发器、存储过程、存储函数的概念、作用,以及如何使用索引、存储过程,代码操作演示
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (含react-draggable库以及相关BUG如何解决)固定在左上方某盒子内(如按钮)添加可拖动功能,使用react hook语法实现
  • (欧拉)openEuler系统添加网卡文件配置流程、(欧拉)openEuler系统手动配置ipv6地址流程、(欧拉)openEuler系统网络管理说明
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (一)SpringBoot3---尚硅谷总结
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .NET Core WebAPI中封装Swagger配置
  • .NetCore项目nginx发布