python为什么不能向量化map()或列表推导

Sci*_*Guy 1 python parallel-processing simd vectorization python-multiprocessing

我对向量化了解不多,但是我想了解为什么像python这样的语言无法通过库接口在可迭代对象上提供向量化,就像它提供线程支持一样。我知道许多numpy方法都是矢量化的,但是对于通用计算必须使用numpy可能会受到限制。

我目前的理解是,即使python与“ SIMD”模式匹配,它们也无法向量化它们。例如,理论上不应该对列表的理解或对该map()函数的使用进行矢量化处理,因为它们会输出一个列表,这是对来自输入列表的独立输入运行相同功能的结果吗?

凭着我的敏锐理解,似乎map()从理论上讲,无论何时我使用,我都应该能够创建一个代表该功能的指令集。那么输入中的每个元素只需通过已编译的同一函数运行即可。设计一种工具的技术挑战是什么,该工具会simd_map(func, iterable)尝试func“及时” 编译,然后从iterable处理器中提取批输入并利用处理器的simd功能来运行这些批处理func()

谢谢!

Pet*_*des 5

所应用的操作map是任意的Python代码。CPython是解释器,而不是JIT编译器。

CPython的可能,也许有一些罐装的C函数(名列前茅的时间编译为解释部分)超过阵列SIMD操作,但是它没有AFAIK。即使这样,它也必须将提供的内容优化func到可以进行模式识别的程度,以注意到它正在执行操作a[i] = max(a[i], some_value)

但是通常CPython 不会这么做;对于循环遍历数组元素而言,解释器开销是一个巨大的问题。 CPython的是无处附近的本地标量循环,表现所以有巨大的空间的收益,即使没有自动矢量。 像IIRC慢200的因子。例如,为什么位运算符比乘法/除法/模运算慢?显示了某些操作甚至没有针对小整数的“快速路径”,并且开销&//在内部使用硬件除法指令的速度要慢得多。

此外,Python列表不存储作为简单连续的阵列int32_tdoubleCPU SIMD所以效率不高反正。这就是numpy数组之所以与众不同的原因:它们确实将值存储为原始类型的C数组。


(注意:我几乎不了解Python,并且不经常使用它。但是我想我足够知道这个答案是正确的:这是用C语言编写的解释器,它不会即时生成本机代码唯一可以运行的本机循环是作为解释器一部分或在NumPy库中预编译的循环。)