并行化的Python程序表现不尽如人意

时间:2015-10-28 09:15:59

标签: python multithreading runtime

我是Python中多线程编程的新手,所以我编写了以下脚本作为练习。它只是生成一个随机的5000x5000整数矩阵,并计算条目的总和。在脚本中,我编写了单线程和多线程版本,以进行简单的速度比较。这是脚本:

import random
import sys
import threading

MATRIX_SIZE = 5000

class ArraySumThread(threading.Thread):

    def __init__(self, data):
        super(ArraySumThread, self).__init__()
        self.data = data
        self.total = None

    def run(self):
        tot = 0

        for i in range(len(self.data)):
            tot += self.data[i]

        self.total = tot

def generate_random_matrix(size):
    return [[random.randint(1, 10) for i in range(size)] for j in range(size)]

def single_thread_test(size):
    matrix = generate_random_matrix(size)
    total = 0

    for i in range(len(matrix)):
        for j in range(len(matrix[0])):
            total += matrix[i][j]

    return total

def multi_thread_test(size):
    matrix = generate_random_matrix(size)
    threads = [None for i in range(size)]

    for i in range(len(matrix)):
        threads[i] = ArraySumThread(matrix[i])
        threads[i].start()
        threads[i].join()

    total = 0

    for thread in threads:
        total += thread.total

    return total

if __name__ == '__main__':
    if '--single' in sys.argv:
        single_thread_test(MATRIX_SIZE)

    elif '--multi' in sys.argv:
        multi_thread_test(MATRIX_SIZE)
    print 'Done.'

使用UNIX time函数计算执行时间,我得到以下结果:

$ time python thread_test.py --single
Done.

real    0m41.814s
user    0m41.575s
sys     0m0.197s
$ time python thread_test.py --multi
Done.

real    0m44.536s
user    0m43.568s
sys     0m2.539s

这没有意义,因为多线程版本应该更快(我在MacBook Pro视网膜上运行它,以供参考)。我知道多线程版本确实需要额外的时间来进出内核以切换正在运行的线程,但即使在用户模式下花费的时间也更长。

我忘记了什么吗?是否需要设置其他配置以使用两个处理器?

1 个答案:

答案 0 :(得分:0)

此代码完全由CPU限制,并且将完全在CPython中运行,因此GIL可防止任何并行化,并且实际上由于上下文切换的成本而导致速度减慢。

如果你想加快这种数字工作,你应该考虑NumPy;无论如何你都会得到一个加速,因为它将大量的工作卸载到纯C上,但另外这意味着你应该能够并行化它。