1

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)
4

1 回答 1

0

这些类型 (FC) 表示矩阵(或多维数组)是以列为主(C如在使用列为主存储的 C 语言中)还是以行为主(F如在使用行为主存储的 Fortran 语言中) .

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

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

于 2016-09-29T13:35:52.387 回答