在IPython上执行某些函数比普通python函数慢

2024-05-18 11:06:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在测试ipython的一些功能,我觉得我做错了什么。在

我在测试三种不同的方法来执行一些数学运算。在

  • 第一次使用@parallel.parallel(view=dview, block=True)和函数map
  • 第二次使用单核函数(python normal函数)
  • 第三次使用客户端负载平衡功能

我有这个代码:

from IPython import parallel
import numpy as np
import multiprocessing as mp
import time

rc = parallel.Client(block=True)
dview = rc[:]
lbview = rc.load_balanced_view()

@parallel.require(np)
def suma_pll(a, b):
    return a + b

@parallel.require(np)
def producto_pll(a, b):
    return a * b

def suma(a, b):
    return a + b

def producto(a, b):
    return a * b

@parallel.parallel(view=dview, block=True)
@parallel.require(np)
@parallel.require(suma_pll)
@parallel.require(producto_pll)
def a_calc_pll(a, b):
    result = []
    for i, v in enumerate(a):
        result.append(
            producto_pll(suma_pll(a[i], a[i]), suma_pll(b[i], b[i]))//100
        )
    return result

@parallel.require(suma)
@parallel.require(producto)
def a_calc_remote(a, b):
    result = []
    for i, v in enumerate(a):
        result.append(
            producto(suma(a[i], a[i]), suma(b[i], b[i]))//100
        )
    return result

def a_calc(a, b):
    return producto(suma(a, a), suma(b, b))//100

def main_pll(a, b):
    return a_calc_pll.map(a, b)

def main_lb(a, b):
    c = lbview.map(a_calc_remote, a, b, block=True)
    return c

def main(a, b):
    c = []
    for i in range(len(a)):
        c += [a_calc(a[i], b[i]).tolist()]
    return c

if __name__ == '__main__':
    a, b = [], []

    for i in range(1, 1000):
        a.append(np.array(range(i+00, i+10)))
        b.append(np.array(range(i+10, i+20)))

    t = time.time()
    c1 = main_pll(a, b)
    t1 = time.time()-t

    t = time.time()
    c2 = main(a, b)
    t2 = time.time()-t

    t = time.time()
    c3 = main_lb(a, b)
    t3 = time.time()-t    

    print(str(c1) == str(c2))
    print(str(c3) == str(c2))
    print('%f secs (multicore)' % t1)
    print('%f secs (singlecore)' % t2)
    print('%f secs (multicore_load_balance)' % t3)

我的结果是:

^{pr2}$

为什么我的多核程序比单核程序慢?这种方法有什么问题?我能做些什么来修复它?在

一些信息:python3.4.1,ipython2.2.0,numpy 1.9.0,ipcluster用LocalEngineSetLauncher启动8个引擎


Tags: truereturntimeparallelmaindefnpcalc
1条回答
网友
1楼 · 发布于 2024-05-18 11:06:15

在我看来,您正在尝试并行化一些只需在单个核心上执行的时间太少的东西。在Python中,任何形式的“真正”并行都是多进程的,这意味着您必须生成多个Python解释器,通过pickling/unpickle等方式传输数据

这将导致小工作负载的显著开销。在我的系统中,只需启动然后立即停止Python解释器大约需要1/100秒:

# time python -c "pass"

real    0m0.018s
user    0m0.012s
sys     0m0.005s

我不确定您使用的装饰器在幕后做什么,但是正如您所看到的那样,为并行工作设置基础设施可能需要相当长的时间。在

编辑

在进一步的检查中,您似乎已经在运行代码之前设置了workers,因此上面暗示的开销可能不在考虑范围之内。在

不过,您正在将数据移动到worker进程,这两个列表包含1000个NumPy数组。在我的系统中,对字符串进行ab的酸洗时间为~0.13秒,使用pickle需要~0.046秒。通过将数组存储在NumPy数组中而不是列表中,可以减少酸洗时间:

^{pr2}$

这将cPickle时间缩短至~0.029秒。在

相关问题 更多 >