程序员在编写Python代码时是否需要手动实现循环展开等优化?

问题描述 投票:0回答:1

我最近正在学习一些 HPC 主题,并了解到现代 C/C++ 编译器能够检测有权优化的位置,并使用相应的技术(例如 SIMD、循环展开等)进行优化,特别是在

-O3
标志下,运行时性能与编译时间和目标文件大小之间的权衡。

然后我立即想到 CPython 是即时解释和执行的,所以我认为它无法承担这些编译器功能,因为它的编译时间相当于运行时,所以我做了一个下面的玩具实验:

import time, random

n = 512
A = [[random.random() for _ in range(n)] for _ in range(n)]
B = [[random.random() for _ in range(n)] for _ in range(n)]
C = [[0] * n for _ in range(n)]

def matMul( A, B, C ):
    """ C = A .* B """
    for i in range(0, n - 4, 4):
        for j in range(0, n - 4, 4):
            for k in range(0, n - 4, 4):
                C[i][j] = A[i][k] + B[k][j]
                C[i + 1][j + 1] = A[i + 1][k + 1] + B[k + 1][j + 1]
                C[i + 2][j + 2] = A[i + 2][k + 2] + B[k + 2][j + 2]
                C[i + 3][j + 3] = A[i + 3][k + 3] + B[k + 3][j + 3]
                C[i + 4][j + 4] = A[i + 4][k + 4] + B[k + 4][j + 4]
    # return C

start = time.time()
matMul( A, B, C )
end = time.time()

print( f"Elapsed {end - start}" )

随着循环的展开,程序会在3秒内完成,如果没有循环,则需要将近20秒。

这是否意味着在编写Python代码时需要注意并手动实现这些opt技术?或者Python是否提供任何特殊设置下的优化?

python c optimization compilation hpc
1个回答
0
投票

循环展开非常有用,因为它可以 (1) 减少管理循环所花费的开销,并且 (2) 在汇编级别,它可以通过消除分支惩罚、保持指令管道满等来让处理器运行得更快。

(2) 并不真正适用于像 Python 这样的解释语言实现 - 它已经在汇编级别进行了大量的分支和决策。它可能会给你带来(1)的好处,但我的直觉是,与口译员的开销相比,这个时间往往显得相形见绌。性能优化的黄金法则是首先测量并确认瓶颈就在你认为的地方。

顺便说一句,你的代码有一个错误:

                C[i][j] = A[i][k] + B[k][j]
                C[i + 1][j + 1] = A[i + 1][k + 1] + B[k + 1][j + 1]
                C[i + 2][j + 2] = A[i + 2][k + 2] + B[k + 2][j + 2]
                C[i + 3][j + 3] = A[i + 3][k + 3] + B[k + 3][j + 3]
                C[i + 4][j + 4] = A[i + 4][k + 4] + B[k + 4][j + 4]

它处理单元格 (0, 0)、(1, 1)、(2, 2)、(3, 3) 和 (4, 4)(即使 (4, 4) 也将在下一次迭代中处理),但不是 (0, 1)、(0, 2)、(1, 0)...(这就是性能优化黄金法则的other原因:优化以下代码很容易犯错误:不需要它。)

正如 @Mat 所说,Python 的标准方法尤其是使用 NumPy,它使用优化的 C 实现。

以上所有内容都适用于 CPython,即标准 Python 实现。还有其他 Python 实现,例如 Cython,它们提供了自己的优化;我对这些不太熟悉。

© www.soinside.com 2019 - 2024. All rights reserved.