numpy 矢量化是硬件/框架特定的功能,还是良好的编码实践?

vmjh9lq9  于 2023-08-05  发布在  其他
关注(0)|答案(3)|浏览(87)

我试图将我的头围绕矢量化(用于数值计算),我遇到了看似矛盾的解释:

  • 我的理解是,它是一个内置在低级库中的特性,它利用给定处理器的并行处理能力,同时对多个数据点执行操作。
  • 但是一些教程似乎将其描述为一种编码实践,可以将其纳入代码中以提高效率。如果它也是您正在使用的框架中具有或不具有的功能,那么它如何成为编码实践。

更具体地解释我的困境:

  • 假设我有一个循环来计算Python中一个数字列表的运算。为了将其向量化,我只需导入Numpy,然后使用数组函数一步完成计算,而不必编写耗时的循环。Numpy使用的低级C例程将代表我完成所有繁重的工作。

据我所知,了解Numpy以及如何导入和使用它并不是一种编码实践。这只是对工具和框架的良好了解,仅此而已。
那么,为什么人们一直把矢量化作为一种优秀的编码人员在代码中利用的编码实践呢?

b09cbbtk

b09cbbtk1#

矢量化在不同的上下文中可以意味着不同的东西。在numpy中,我们通常指的是使用编译的numpy方法来处理整个数组。实际上,这意味着将任何循环从解释型Python中移到编译代码中。它是numpy的特殊性。
几年前我从MATLAB来到numpy,在此之前是APL(以及作为学生的物理/数学)。因此,我已经习惯于考虑整个数组/向量/矩阵很长一段时间了。
MATLAB现在有很多即时编译,所以程序员可以编写迭代代码而不会影响性能。numba(和cython)允许numpy用户做一些相同的事情,尽管仍然有很多粗糙的边缘-正如可以在numpa标记的问题中看到的那样。
并行化和利用现代多核计算机的其他手段是一个不同的主题。这通常需要使用额外的包。
我对循环不是Python的评论提出异议。我应该稍微修饰一下。Python确实有一些工具来避免大的、难以读取的循环,比如列表解析、生成器和其他解析。通过将解析和生成器串在一起来执行复杂的任务是很好的Python实践,但这不是“向量化”(在numpy的意义上)。

mf98qq94

mf98qq942#

矢量化充分利用了现代处理器的SIMD(单指令多数据)指令集。例如,假设您的数据是32位,在过去,一次加法将花费一条指令(根据体系结构的不同,假设为4个时钟周期)。英特尔最新的SIMD指令集现在可通过一条指令同时处理512位数据,支持您并行进行16次加法运算。除非您正在编写汇编代码,否则最好确保代码经过高效编译,以利用SIMD指令集。这是由标准软件包来解决的。
您的下一个加速机会是编写代码以利用多核处理器,并将循环从解释的python中移出。同样,这也是通过库和框架来解决的。
如果您是一名数据科学家,您应该只关心调用正确的包/框架,避免重新实现库已经提供的逻辑(循环是一个主要的示例),而只关注您的应用程序。如果您是一个框架/低级代码开发人员,您最好学习良好的编码实践,否则您的包将永远无法运行。

os8fio9y

os8fio9y3#

......为什么人们一直将矢量化视为优秀编码人员所利用的一种编码实践......?
因为为了开始看到矢量化的机会,需要一个思维转变,在开始构建任何解决方案之前,开始看到它的机会,选择用于实现这一点的框架,或代码本身。

* 是否为SIMD?*

好吧,* 不是 * 在你提出问题的背景下。
虽然编译器可能允许强制转换为SIMD硬件似真机器码(@B_F提到的),但在使用解释的Python时,这通常不是您的选择。Python模块可以利用这个低级的技巧,如果这些模块是用这种SIMD强制和/或其他避免循环的选项(类似于-O3循环展开 * 几乎狂热的 * 代码转换所允许的)进行预编译的。
同样,不是您在代码架构设计期间的选择,而是一个明智的选择,并重用了工程团队数百年的经验,他们将自己的专业知识和努力投入到使Python模块最大限度地利用硬件上。最后,但并非最不重要的是,SIMD硬件是昂贵的,因为如果在乱序X流水线超标量CISC处理器规范中,则对于功率预算、时钟、处理器微操作重新对准,在硅中以一些显著的成本来决定和实现SIMD硬件。
然而,SIMD原则上只能做几个(向量-(小)-宽度对齐)V-FADD、V-FMUL、V-FMADD、一些《双城之战》宽度定向布尔运算,因此机器代码转换可以在自动化 (不是手动的,在那里真正能做这项工作的人可以为一个特定的实现残酷的加速,并且出于明显的原因,通常在相当重要的,类似HPC,因此使用成本高昂) SIMD强制编译,关注范围非常狭窄,并且此类转换的通用性有限。
虽然计算策略的手动转换可以引入SIMD硬件指令,端到端数字处理的启动时间从几天缩短到约12分钟(作者手动地这样做了一段时间),这样的任务主要是在自动代码转换器的范围之外,在任何编译器中预先编码,这由于明显的原因而限制了语法分析的范围和深度,并且为SIMD注入机会寻找一些浅的、窄范围的机会。因此,这样做的结果基本上是不可比拟的,而不是相互竞争的(谁会愿意在余生中做这样辛苦的抓挠和拔头发的工作呢?).
它是numpy[:]的语法糖吗?
嗯,也不是。
Numpy精心设计了一种矢量化代码方法,以便在Python用户群中大量重用
对于Numpy的作者来说,这顶帽子是要被提升的,因为他们在其他解释的Python中大量使用了这个新概念。性能提升可能会给我们留下深刻印象,但核心优势并不在于执行向量/矩阵/Tensor公式化运算的性能。

核心推动力在于改变我们的思维方式

让我概括一下这个观点。计算机科学的教授要比人们开始编码晚得多。在表达我们计算某个事物(无论是一个数字还是控制一个打印过程等)的意愿的过程中,编程最经常(除了聪明、明智和非常罕见的例外)表现为遵循一些语法规则。这使我们开始相信一种过分简单化的观点,认为只要开始一系列的步骤就足够了,以一种连续的方式,一步接一步,从A到Z进行思考。
虽然这对于开始是足够的,但迟早一个人会到达一个点,这不是在这样一个容易实现的概念之内。在这里,一系列的技巧开始了(无论是转变为事件驱动的框架,模拟在多个事件流中某种控制并发执行,还是函数编程的依赖链,允许我们不考虑执行本身,而是关注函数重新制定的问题描述)。
所有这些都要求我们在思维上对计算策略的看法发生急剧变化。
同样,高效利用矢量化代码也是如此。首先,你必须意识到范式的彻底改变,并开始以一种非**[SERIAL](一步接一步-下一步-下一步) 的方式思考。
什么是更多的 * Python * v/s什么是最重要的?
请原谅我不想插手此事。福音传播对工作队团队的共同教育很重要,他们需要分享一些工作文化。在这样的范围之外,这个主题不会产生任何附加价值,而且容易使我们的宝贵时间和注意力偏向于伪精英主义者的斗争,在一个特定的SLOC中,谁是“更多”的--Python * 或“最多Python *”,而做聪明生意的艺术,或尖端科学,无论哪一个都有当代计算能力的支持,到目前为止都不是一个关于设计任何单个SLOC块的点。

让我们让这些观点的传播者,谁试图尽最大努力重新塑造否则野生和最初分歧的人群力量,至少不破坏尽可能多的公共工作在进展中或多或少自发流的开发设计思想和他们的迭代修订的一些未来的包和/或维护现有的或遗留的。

结语:

  • 矢量化 * 本身 * 奖励一个人,如果能够改变一个人的精神观点。
  • 矢量化不仅仅是SIMD注入
  • 矢量化不仅仅是Numpy(numba和其他工具可以利用这个概念,因为Numpy从FORTRAN/HPC级计算实践中“借用”了同样的智能执行原因,并且自引入以来一直使用FORTRAN库多年,不是吗?)
  • 矢量化有助于摆脱纯[SERIAL]的计算策略,当相同的操作被执行时,“沿着”整个矢量,“穿过”整个矩阵,“穿过”整个Tensor
  • 向量化可以允许在自卷积或跨越技巧相关的计算微策略中的一些智能技巧,其中智能存储器访问重新组织可以帮助更好地重新使用预先缓存的值(速度快~ 100倍,比从主RAM中一次又一次地重新获取它们)-可以自由地阅读大师赛的任何内容- @Divakar或@hpaulj查看示例,展示了将这一过程发挥到极致的实际能力
  • 向量化是一个通用的原则,但它的效果取决于所使用的框架的实际智能和聪明程度(不是语法的自动属性-实现决定)
  • 矢量化越强大,你就越可以在数学上重新制定正在审查的计算策略,它远远不仅仅是一个循环避免器**:o)**人们可以强制Numpy以矢量化的方式在对象的矢量上工作,所以不仅可以使用以数字为中心的运算,然而,智能缓存重用和其他Numpy强大功能的影响(从它的FORTRAN祖先继承而来的)将保持不那么超级高效,因为它们是纯粹的,记忆单元对齐,高速缓存行优化,数字运算
  • 向量化并不是什么新鲜事- Thinking Machines早在20世纪80年代就创建了向量机,并且CDC在他们之前大约二十年就开创了向量处理器,因此在太阳下并不是什么新鲜事,但是上面解释的自动(机器驱动)代码转换为向量的效率决定了处理结果时的性能提升水平。
  • 到目前为止(截至2020-04年),向量化不会自动在NUMA资源上使用众核/跨核执行(除非包作者在用户级视图中隐藏NUMAPlayground上的众核工作分割,这不是一个容易的步骤,不是吗?),因此不要高估自动化代码转换到本地主机但NUMA分布的代码片段的执行的(机器/NUMA相关的)调度的能力。这样做的成本智能,普遍和自动是超出我的想象(如果有一些投资者谁会赞助这一点,他们很可能不会愿意“分享”的成果,这样的投资到一般公众使用,他们会吗?)

相关问题