大部分执行时间都花在执行两个独立函数计算上的代码是使用两个CPU的明显候选者。我知道如何在 Python 中使用multiprocessing
来做到这一点,但只能将成语if __name__ == '__main__':
添加到程序的入口点。在现代Python中是否有更简单的方法(撰写本文时为3.8.3(?那里似乎没有什么是合适的简单。
要求:调用代码不更改,无单独文件。import
一些帮手是可以的,但我宁愿不pip
.
密码学领域的应用和基准测试示例:
def rsacrt(p,q,dp,dq,qi,x):
# most of the time is spent in the following two lines
u = pow(x,dp,p)
v = pow(x,dq,q)
return (u-v)*qi%p*q+v
# test and benchmark the above
import time
e,p,q = 3, 5**3528+12436, 7**2918+27562
n,dp,dq,qi = p*q, pow(e,-1,p-1), pow(e,-1,q-1), pow(q,-1,p)
x = 42
t = time.time()
y = rsacrt(p,q,dp,dq,qi,x)
t = time.time()-t
if pow(y,e,n)!=x: print("# wrongo, spasmoid!")
print("duration of rsacrt:",(int)(t*1000.),"ms")
所示操作是 RSA 签名生成和 RSA 解密中的一个瓶颈。参数故意很高(16384 位 RSA,而不是通常的 2048 位(,因此执行时间以秒为单位,前两个pow
为>98%。这是为了说明并行执行很重要的真实案例,而不是作为如何执行 RSA 的示例:有快速的替代方案来替代pow
,并且此代码缺乏侧信道保护。
注意:此代码需要一个 Python 版本,pow
可以在其中计算模逆。这包括Python 3.8.x。在线试用!
补充:在 Python 3 下工作的代码要大得多,请参阅其他在线尝试!
使用multiprocessing
时,只有模块的顶级范围才需要if __name__ == '__main__'
保护。multiprocessing
和派生模块可以直接在函数中使用。
对简洁的 API 使用multiprocessing.Pool
或concurrent.futures.ProcessPoolExecutor
:
def rsacrt(p,q,dp,dq,qi,x):
with concurrent.futures.ProcessPoolExecutor() as executor:
u, v = executor.map(pow, *zip((x, dp, p), (x, dq, q)))
return (u-v)*qi%p*q+v
这大约将rsacrt
速度提高了 2 倍。