![]() |
1
16
热身作为热身,考虑两个简单的例子。
这是审慎的分析。”“矢量化”从循环展开开始,然后并行执行多条指令。循环是否可以“矢量化”取决于循环所承载的数据依赖关系。
一个接一个地执行这些指令并同时执行它们会得到相同的结果。所以这个循环可以“矢量化”。 示例2中的循环是
在“矢量化”理论中,
具有“先读后写”数据依赖关系的循环可以“矢量化”,而具有“先读后写”数据依赖关系的循环则不能。 深入也许现在很多人都困惑了。”“矢量化”是“并行处理”吗?
在1960年代,编程语言并不多。人们编写汇编程序(当编译器发明时是FORTRAN)直接对CPU寄存器进行编程。“SIMD”计算机能够用一条指令将多个数据加载到向量寄存器中,并同时对这些数据执行相同的算法。所以数据处理确实是并行的。再次考虑我们的示例1。假设一个向量寄存器可以容纳两个向量元素,那么循环可以使用向量处理执行5次迭代,而不是标量处理中的10次迭代。
今天有很多编程语言,比如 R R 不是一种可以编程CPU寄存器的语言。R中的“矢量化”只是“SIMD”的一个类比。在以前的问答中;答: Does the term "vectorization" mean different things in different contexts?
所以,示例1中循环的R“矢量化”类似于
大多数时候我们只是
没有显式地将临时向量赋给变量。创建的临时内存块没有被任何R变量指向,因此要进行垃圾收集。 在上面,“矢量化”不是用最简单的例子介绍的。通常,“矢量化”是通过以下方式引入的
回到问题中的例子
第3条和第5条指令之间存在“先读后写”的数据依赖关系,因此循环无法“矢量化”(请参阅) 备注1
那么,那是什么呢
自
备注1
this Q & A . OP最初提出了一个循环
但这可能是错误的。后来OP把循环改成
这消除了内存混叠问题,因为要替换的列是第一列
备注3
关于问题中的循环是否正在对
但是,循环没有进行“就地”排列“就地”置换是一个更复杂的操作。不仅仅是
|
![]() |
2
3
有一个更简单的解释。使用循环,您将覆盖
对于矢量化代码,您只需要对
这里没有混淆的危险:
|
![]() |
3
3
这与内存块别名无关(我以前从未遇到过这个术语)。以一个特定的排列为例,遍历在C语言或汇编语言(或任何语言)级别上的实现都会发生的赋值;它是任何顺序for循环的行为与任何“真正”排列的行为之间的内在联系
... 可以继续,但这说明了这通常不是一个“真正的”排列,而且非常罕见地会导致价值的完全再分配。我猜只有一个完全有序的排列(我认为只有一个,即。
|
|
4
2
有趣的是,尽管R“矢量化”不同于“SIMD”(正如OP很好地解释的),但在确定循环是否“可矢量化”时,同样的逻辑也适用。下面是一个演示,使用OP的self-answer中的示例(稍加修改)。 具有“读后写”依赖关系的示例1是“可矢量化的”。
不 “可矢量化”。
使用C99
|
|
Marc B. · 使用ggplot2创建条形图时“缺少值” 1 年前 |
|
Mallikarjun M · 如何使用随机森林进行时间序列预测? 1 年前 |
|
ly li · 模型摘要:当表格形状改变时,拟合优度消失 1 年前 |
![]() |
RoyBatty · 统计每个字符在整个数据集中出现的次数 2 年前 |
![]() |
stats_noob · R: 记录某个“行为”发生的循环的索引? 2 年前 |