有利于循环展开的条件和返回边际减小的点
Conditions for loop unrolling to be beneficial and the point at which margins of return decrease?
谁能先解释一下在什么时候展开循环(在C/c++)成为一个有用的优化做?
第二,与第一个问题相关,在什么情况下不应该再执行展开?展开是否应该总是将操作分成2次幂的批?或者它是否与CPU可以执行多少计算有关?一个比率,它是缓存线大小的乘数?等
例如,如果我有一个从0到99的For循环哪个更好/我如何确定哪个(除了试错)-有科学的方法吗:
- 0到49,每个循环两次"操作"
- 0到24,每个循环4个"操作"
- 0到19,每个循环5个"操作"
- 每个循环0到9和10个"操作"
我不能让一个关于循环展开的问题没有回答这么长时间而不提到达夫设备。这个实现与经典版本略有不同,但它仍然可以工作。
假设你在一个内存块上应用一个掩码:
while (n-- > 0) {
*ptr++ &= mask;
}
然后,它可以像这样展开:
switch (n % 4) do {
case 0: *ptr++ &= mask;
case 3: *ptr++ &= mask;
case 2: *ptr++ &= mask;
case 1: *ptr++ &= mask;
} while ((n -= 4) > 0);
如果迭代跳转的成本占循环迭代内完成的工作成本的很大比例,那么循环展开是有用的。一个好的优化编译器可以在足够的优化级别上为您解决这个问题。只有当编译器无法展开时,你才需要自己展开。
正如在注释中提到的,一旦跳跃的计算成本与展开循环体的计算相比不再显著,就不需要展开循环。在极端情况下,循环展开可能导致指令缓存震荡,损害性能(类似于过度使用函数内联)。
相关文章:
- 架构决策:返回std::future还是提供回调
- 如何使用从处理程序调度的最终回调将响应异步返回给调用方on_read?
- C++ 线程端回调并返回结果
- 返回字符串的散点回文计数
- 具有返回类型的回调函数
- 在 winapi 回调函数上返回 FALSE 时出现意外行为(循环被跳过?
- 如何在不转换回基类类型的情况下返回派生类型的对象?
- 如何知道 sqlite 中的函数"回调"是否返回了一些东西?
- 是否可以在C 中使回调函数返回值
- C++-17变量模板:捕获回调参数的返回类型和参数类型
- 为什么我的回文函数总是返回假
- 带有lambda的C++回调失败,返回bad_function_call
- 一个回调函数应该如何更新/返回值
- 未知类方法回调,它接受 0 个参数并返回可转换为 int 的类型
- C++,pthread和静态回调。 "this" 返回一个指针,指向派生的基类(第 2 部分)
- 在返回值和"回调"之间做出决定时的样式与一致性
- c++调试返回0回变量
- Boost Python回调返回auto_ptr删除对象
- c++函数中的回文返回false
- Curl 的CURLOPT_XFERINFOFUNCTION回调返回 dlnow > dltotal