问题标签 [loop-unrolling]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
2328 浏览

python - 优化工具

我想知道有什么工具可以在循环展开方面优化我的程序,我该如何使用它?

我有以下python代码:

我想优化这个代码段,以便我可以尝试理解循环展开。使用 Python,我想知道一个 C 优化器。

0 投票
1 回答
1544 浏览

loop-unrolling - 展开一个while循环

原始代码

展开 while 循环

我们不能如上所示展开它。我们是否总是必须像http://en.wikipedia.org/wiki/Loop_unrolling那样做?

0 投票
1 回答
251 浏览

c++ - 如何向编译器提示循环运行的最长时间

如上代码所示,我的猜测是,如果我只是写

for (; in_x != 0; in_x >>= 1)

编译器不会展开循环,因为它不能确定最大可能的 in_x。

我想知道我是对还是错,以及是否有更好的方法来处理这些事情。


或者问题可以概括为好像可以编写一些代码来告诉编译器某个运行时值的范围,而这样的代码不一定被编译成运行时二进制文件。


真的,和编译器打架 XD

0 投票
1 回答
736 浏览

loops - 循环展开以实现并行性

在一次讲座中,我的教授给了我们以下循环:

他指出了循环迭代之间的依赖关系,因为第 3 行设置了一个值,该值将在第 2 行的下一次迭代中使用(设置在下一次迭代b[i+1]中成为b[i])。因此,我们不能并行运行循环的每次迭代。

然后他给了我们这个展开的版本:

他声称循环的每次迭代现在都可以并行运行。我看到的问题是第 3 行设置了b[i]第 4 行的下一次迭代中的内容,因此我们仍然不能并行运行每个迭代。

我这样说对吗?如果是这样,是否有第一个循环的正确展开版本,其中每次迭代都可以并行化?

0 投票
1 回答
838 浏览

c - 循环展开对内存绑定数据的影响

我一直在使用一段受内存密集限制的代码。我试图通过手动实现缓存阻塞、sw 预取、循环展开等在单个内核中对其进行优化。即使缓存阻塞显着提高了性能。但是,当我引入循环展开时,性能会大大下降。

我在所有测试用例中都使用带有编译器标志 -O2 和 -ipo 的 Intel icc 进行编译。

我的代码与此类似(3D 25 点模板):

当我在最内层循环(维度 i)上进行循环展开并分别以展开因子 2、4、8 分别在 x、y、z 方向上展开时,我在所有 9 种情况下都会出现性能下降,即在方向 x 上展开 2,展开在 y 方向上展开 2,在 z 方向上展开 2,在 x 方向上展开 4 ... 等等。但是当我在最外面的循环(维度 k)上执行循环展开 8 倍(也有 2 和 4)时,我获得 v.good 性能改进,甚至比缓存阻塞更好。

我什至尝试使用 Intel Vtune 分析我的代码。这似乎是主要由于远程 DRAM 服务的 1.LLC 未命中和 2.LLC 负载未命中造成的瓶颈。

我无法理解为什么展开最内层最快的循环会导致性能下降,而展开最外层、最慢的维度会带来性能提升。然而,后一种情况的这种改进是当我使用 icc 编译时使用 -O2 和 -ipo 时。

我不确定如何解释这些统计数据。有人可以帮助阐明这一点。

0 投票
4 回答
3604 浏览

c++ - 现代编译器能否展开使用开始和结束迭代器表示的“for”循环

考虑以下代码

像 g++、clang++、icc 这样的编译器是否能够展开这样的循环。不幸的是,我不知道程序集能够从输出中验证循环是否展开。(而且我只能访问 g++。)

对我来说,这似乎代表编译器需要比平常更多的智能,首先推断迭代器是随机访问迭代器,然后计算循环执行的次数。启用优化后编译器可以这样做吗?

感谢您的回复,在你们中的一些人开始讲授过早优化之前,这是一个好奇的练习。

0 投票
2 回答
86 浏览

c++ - 如何确保在 C++ 编译期间参数将被视为常量?

我想知道以下两个实现是否会产生完全相同的东西并具有相同的性能,无论我使用什么编译器:

在第一个中,由于循环中使用的 TSIZE 是一个模板参数,因此几乎可以保证编译器会在需要时展开循环。如果循环在第一种情况下展开,是否会在第二种情况下展开(唯一的区别是 TSIZE 存储在静态常量中)?

非常感谢你。

0 投票
2 回答
1662 浏览

c - 循环展开(按位运算)

我正在编写一个 Linux 内核驱动程序(用于 ARM),并且在一个 irq 处理程序中我需要检查中断位。

请注意,一次可以设置多个位。

所以这是代码:

(1 << 0)并且(1 << 16)会在编译时计算,但是(1 << i)不会(1 << (i + 16))。循环中也会有积分比较和加法。

因为它是一个 irq 处理程序,所以应该在最短的时间内完成工作。这让我想我是否需要对其进行一些优化。

可能的方法?

1.拆分循环,好像没什么区别...

2.移位intr而不是要比较的值?

3.完全展开循环(未显示)。这会使代码有点混乱。

4.还有其他更好的方法吗?

5.还是编译器实际上会生成最优化的方式?


编辑:我正在寻找一种方法来告诉 gcc 编译器展开该特定循环,但根据我的搜索似乎不可能......

0 投票
2 回答
1770 浏览

optimization - 在什么类型的循环中最好在 CUDA 中使用 #pragma unroll 指令?

在 CUDA 中,可以使用#pragmaunroll 指令展开循环,以通过增加指令级并行度来提高性能。可以选择#pragma后跟一个数字,指定循环必须展开多少次。

不幸的是,文档没有给出何时应该使用该指令的具体说明。由于具有已知行程计数的小循环已经被编译器展开,是否应该#pragma在较大的循环上使用展开?在带有可变计数器的小循环上?那么可选的展开次数呢?还有关于 cuda 特定循环展开的推荐文档吗?

0 投票
1 回答
1629 浏览

c - 循环展开及其对流水线和CPE的影响(有解决方案,但不明白)

下面是一个关于练习测试的问题。该表实际上已填写了所有解决方案。但是,我需要澄清为什么这些解决方案是这样的。(阅读水平线下方的问题)。

例如,我真的很想了解 A2 和 A3 的解决方案行。

正如我所看到的,您在 A2 中遇到以下情况:

  1. x * y
  2. xy * r
  3. xyr * z

现在,让我们看看它是如何进行的:

所以我们能够重叠 xyr * z 和 x2 * y2,因为没有依赖冲突。但是,这只是摆脱了 3 个周期,对吗?

所以它仍然是 (12 - 3) / 3 = 9 / 3 = 3 Cycles Per Element(三个元素)。那么他们如何获得 A2 的 8/3 CPE 呢?

任何帮助理解这个概念将不胜感激!不急,因为考试要到下周。如果您需要任何其他信息,请告诉我!


(以下是完整的测试题文本,以及完整填写解决方案的表格)

考虑以下用于计算 n 个整数数组的乘积的函数。

我们将循环展开了 3 倍。

对于标记为 Product 计算的行,我们可以使用括号来创建五个不同的计算关联,如下所示:

我们用每个元素的周期数 (CPE) 来表示函数的性能。如书中所述,此度量假设运行时间(以时钟周期为单位),长度为 n 的数组是 Cn + K 形式的函数,其中 C 是 CPE。

我们在 Intel Pentium III 上测量了该功能的五个版本。回想一下,这台机器上的整数乘法运算有 4 个周期的延迟和 1 个周期的发出时间。

下表显示了 CPE 的一些值,以及缺少的其他值。测量的 CPE 值是实际观察到的值。“理论 CPE”意味着如果唯一的限制因素是整数乘法器的延迟和发布时间,则可以实现的性能。

在此处输入图像描述

填写缺少的条目。对于测量的 CPE 的缺失值,您可以使用具有相同计算行为的其他版本的值。对于理论 CPE 的值,您可以仅考虑乘法器的延迟和发布时间来确定迭代所需的周期数,然后除以 3。