2014-09-25 46 views
1

我正在测试ipython的一些功能,我想我做错了什么。在IPython上执行某些功能比普通的python函数慢

我测试3种不同的方式来执行一些数学运算。

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

我有这样的代码:

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) 

我的结果是:

True 
True 
0.040741 secs (multicore) 
0.004004 secs (singlecore) 
1.286592 secs (multicore_load_balance) 

为什么我的多核例程比我的单核心例程慢?这种方法有什么问题?我能做些什么来解决它?

一些信息:python3.4.1,IPython的2.2.0,1.9.0 numpy的,ipcluster 8个燃用LocalEngineSetLauncher

回答

1

在我看来,你正试图parallelise的东西,需要的时间太少了执行上一个单一的核心。在Python中,任何形式的“真实”并行性都是多进程的,这意味着你必须产生多个Python解释器,通过酸洗/去除等来传输数据。

这会导致明显的开销工作量小。在我的系统,刚开始,然后立即停止Python解释器需要大约1/100秒:

# time python -c "pass" 

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

我不知道你使用的是装饰在做什么在幕后,但你可以看到只是为并行工作建立基础架构可能需要相当长的时间。

编辑

在进一步检查,它看起来像您已经在运行代码之前设立的工人,这样的开销上面暗示可能出来的图片。

您虽然将数据移动到工作进程,两个1000 NumPy数组列表。酸洗ab到我系统上的字符串需要约0.13秒pickle和约0.046秒cPickle。可以通过存储在阵列来降低酸洗时间,而不是列表,NumPy的数组:

a = np.array(a) 
b = np.array(b) 

这减少了cPickle时间〜0.029秒。

+0

使用这种方法'(A = np.array的(a); B = np.array(B)))',我的结果是: 真 真 0.043795秒(多核) 0.010011秒(单芯) 1.541814 secs(multicore_load_balance) 单核函数增加了它的时间,但其他函数没有。 – xmn 2014-09-26 16:42:55

相关问题