【问题标题】:Addition speed of numpy arrays with different contiguous-type不同连续类型的numpy数组的加法速度
【发布时间】:2017-02-07 20:20:03
【问题描述】:

Numpy 数组以不同的连续类型(C- 和 F-)存储。使用 numpy.swapaxes() 时,连续类型会发生变化。我需要添加两个多维数组(更具体地说是 3d),其中一个来自另一个具有交换轴的数组。我注意到的是,当第一个轴与最后一个轴交换时,在 3d 数组的情况下,连续类型从 C- 变为 F-。并且添加两个具有不同连续类型的数组非常慢(比添加两个 C 连续数组慢约 6 倍)。但是,如果交换其他轴(0-1 或 1-2),则生成的数组将具有 C- 和 F- 连续(非连续)的错误标志。对我来说奇怪的是,添加一个 C 配置数组和一个既不是 C 也不是 F 连续的数组实际上只比添加两个相同类型的数组慢一点。这是我的两个问题:

  1. 为什么 C-&F-连续数组加法和 C-& 非连续数组加法看起来不同?是由不同的重排机制引起的,还是仅仅因为 C- 和 F- 相邻的重排距离对于所有可能的轴顺序来说都是最长的?

  2. 如果我必须添加一个 C 连续数组和一个 F 连续/非连续数组,加快速度的最佳方法是什么?

以下是我遇到的一个最小示例。我电脑上打印的三个持续时间是 2.0s(C-contiguous + C-contiguous)、12.4s(C-contiguous + F-contiguous)、3.4s(C-contiguous + non-contiguous)和 3.3s(C-contiguous) + 不连续)。

import numpy as np
import time

np.random.seed(1234)

a = np.random.random((300, 400, 500))  # C-contiguous
b = np.swapaxes(np.random.random((500, 400, 300)), 0, 2)  # F-contiguous
c = np.swapaxes(np.random.random((300, 500, 400)), 1, 2)  # Non-contiguous
d = np.swapaxes(np.random.random((400, 300, 500)), 0, 1)  # Non-contiguous

t = time.time()
for n in range(10):
    result = a + a
print(time.time() - t)

t = time.time()
for n in range(10):
    result = a + b
print(time.time() - t)

t = time.time()
for n in range(10):
    result = a + c
print(time.time() - t)

t = time.time()
for n in range(10):
    result = a + d
print(time.time() - t)

【问题讨论】:

    标签: python arrays performance numpy contiguous


    【解决方案1】:

    这些类型(FC)表示矩阵(或多维数组)是以列为主(C 与使用列为主存储的 C 语言中一样)还是行为主(F 与使用行优先存储的 Fortran 语言一样)。

    两者的速度并没有真正的不同。它只是一个抽象层。无论您使用哪一个,它都会带来相同的性能。

    然而,产生巨大差异的是数组是否连续。如果它们是连续的,您将有很好的时序原因,因为缓存效果、矢量化和编译器可能应用的其他优化游戏。

    【讨论】:

    • 感谢阿门的及时回复!我知道连续类型是一个抽象层。但是当在 python 中添加两个具有不同连续类型的数组时,似乎进行了某种转换,导致性能非常差。我已经更新了示例代码,它至少在我的计算机上演示了这种行为。
    • 确实,转换开始了。
    猜你喜欢
    • 2022-09-24
    • 1970-01-01
    • 2014-08-12
    • 2015-01-29
    • 1970-01-01
    • 1970-01-01
    • 2020-08-24
    • 2021-05-02
    相关资源
    最近更新 更多