多线程与模拟中的列表理解

时间:2016-11-03 19:35:25

标签: python arrays multithreading

假设我们有一个递归关系

A[0] = a
A[i+1] = f(A[i],c)

其中c是参数,f是某个函数,比如说

def f(x, c):
    return sin(x) + c

假设对于给定的a,我们要评估A[i] for i in range(0,n) c in Cs = [c[j] for j in range(0, m)],其中nm相当大。

用几句话提问:我应该为每个i使用多线程来理解每个c或列表。

让我解释一下。我正在考虑以下两种方法:

方法1:

A[i]存储在2D数组中,每行包含固定c [i]的序列值。但是以列主要顺序存储数组,使得常量i的A [i]是连续的。

然后使用list comprehension来计算它们

for i in range(0,n):
    A[:,i+1] = [f(A[i],c) for c in Cs]

方法2:

如前所述将序列存储在2D数组中,但这次按行主要顺序存储。

有一个给定行的函数用给定c的序列值填充它。

def sequence(j):
    A[j, 0] = a
    for i in range(0, n - 1):
        A[j, i+1] = f(A[j, i], Cs[j])

然后使用sequence调用j在不同的线程进程中的不同multiprocessing.Pool

我更喜欢这两种方法中的哪一种?

实验:

我尝试了以下测试

import numpy
from multiprocessing.dummy import Pool
from multiprocessing import cpu_count
import time

def func(x):
    N = 400
    A = numpy.array([[i*j for i in range(0,N)] for j in range(0, N)])
    h = numpy.array([x for i in range(0, N)])
    y = numpy.dot(A, h.transpose())
    return y[-1]

start_time = time.time()

def multiproc():
    print('Multiple processes')
    print(cpu_count())
    mypool = Pool(cpu_count())
    print(mypool.map(func, [i for i in range(0,100)]))


def multiproc2():
    print('Multiple processes 2')
    pool = Pool(cpu_count())
    res = numpy.empty(100)
    for i in range(0,100):
        res[i] = pool.apply_async(func, (i,)).get()
    pool.close()
    pool.join()
    print(res)

def singleproc():
    for i in range(0,100):
        print(func(i))
    print('Single process')

funcs = [multiproc, singleproc, multiproc2]

funcs[1]()

print("%.6f seconds" % (time.time() - start_time))

更改funcs[1]()funcs[0]()的来电funcs[2](),我们在每种情况下都会得到相同的时间。

1 个答案:

答案 0 :(得分:1)

我更喜欢使用Pool包装器,因为它看起来似乎更好的线程方法。试试这个:

from multiprocessing import Pool
import numpy as np

def f(x, c):
    return sin(x)+c

A = np.zeros(shape=(m, n))
for i in range(n-1):
    pool = Pool()
    res = []
    for j in range(m):
        res.append(pool.apply_async(f, (A[i, j], Cs[j])))
    pool.close()
    pool.join()
    for j in range(m):
        A[i+1, j] = res[j].get()

你可以随时计算两种方法,看看哪一种方法最快:

 import time
 start_time = time.time()
 # your code
 print("%.6f seconds" % (time.time() - start_time))

这不是很准确,但它应该足以达到您的目的。

相关问题