在使用不同数据类型的 numpy 数组进行多重处理时,我遇到了意外错误。首先,我使用 int64
类型的 numpy 数组执行多重处理,并使用 float64
类型的 numpy 数组再次运行它。 int64
按预期运行,而 float64
使用所有可用处理器(比我分配的处理器多),导致计算速度比使用单核慢。
以下示例重现了该问题:
def array_multiplication(arr):
new_arr = arr.copy()
for nnn in range(3):
new_arr = np.dot(new_arr, arr)
return new_arr
if __name__ == '__main__':
from multiprocessing import Pool
import numpy as np
from timeit import timeit
# Example integer arrays.
test_arr_1 = np.random.randint(100, size=(100, 100))
test_arr_2 = np.random.randint(100, size=(100, 100))
test_arr_3 = np.random.randint(100, size=(100, 100))
test_arr_4 = np.random.randint(100, size=(100, 100))
# Parameter array.
parameter_arr = [test_arr_1, test_arr_2, test_arr_3, test_arr_4]
pool = Pool(processes=len(parameter_arr))
print('Multiprocessing time:')
print(timeit(lambda: pool.map(array_multiplication, parameter_arr),
number=1000))
print('Series time:')
print(timeit(lambda: list(map(array_multiplication, parameter_arr)),
number=1000))
将会产生
Multiprocessing speed:
4.1271785919998365
Series speed:
8.102764352000122
这是预期的加速。
但是,将 test_arr_n
替换为
test_arr_1 = np.random.normal(50, 30, size=(100, 100))
test_arr_2 = np.random.normal(50, 30, size=(100, 100))
test_arr_3 = np.random.normal(50, 30, size=(100, 100))
test_arr_4 = np.random.normal(50, 30, size=(100, 100))
结果
Multiprocessing time:
2.379720258999896
Series time:
0.40820308100001057
除了使用所有可用处理器之外,我已指定 4。下面是运行第一种情况 (int64
) 和第二种情况 (float64) 时处理器使用情况的屏幕截图
)。
以上是 int64
情况,其中向四个处理器分配任务,然后由一个处理器串行计算该任务。
但是,在 float64
情况下,即使指定的数量是 test_arr
的数量(即 4),所有处理器都会被使用。
我已经在array_multiplication
中的for
循环中尝试了许多数组大小大小和迭代次数,并且行为是相同的。我运行的是 Ubuntu 16.04 LTS,具有 62.8 GB 内存和 i7-6800k 3.40GHz CPU。
为什么会发生这种情况?提前致谢。
最佳答案
这是预期的行为。
Numpy 使用 BLAS内部(对于某些功能)是高度优化的(缓存、SIMD,并且取决于您使用的实现:多线程;一些候选实现 Atlas、OpenBLAS、MKL),并且仅因某些外部多处理(具有基于 IO 的功能)而减慢速度开销并且也可能损害缓存行为)!
现代 Ubuntu 版本默认带有多线程 BLAS 实现(早期版本仅限于 1 或 2 个线程)。
numpy 中基于 BLAS 的函数的经典示例是 np.dot()
。
大多数 BLAS 实现(我所知道的;看到了一些讨论 @Intel 以向 MKL 添加对离散类型的一些有限支持)only support floating-point types ,这就是为什么这两个代码表现不同的原因(一个高度优化,另一个没有;一个受到多处理的伤害,另一个则没有)。
从技术上讲,我不会称其为错误,但这是您描述的观察结果!
相关question .
关于python - 使用不同数据类型的 numpy 数组进行多重处理时出现意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46200272/