【问题标题】:Handling unrolled loop remainder处理展开的循环余数
【发布时间】:2012-03-15 19:44:16
【问题描述】:

美好的一天。

我想就处理展开的循环剩余部分的技巧寻求贡献,但需要注意的是循环相当小,是展开因子的 1-3 倍,例如:

EG。给定 B 的展开因子

int i = 0;
for (; i < N-N%B; i += B) {
    ...
}
// remainder
for (; i < N; ++i) {
    ...
}

如果 B 为 2,我可以执行以下操作:

// remainder
if (N%2) {
    ....
}

但是有什么好办法处理B&gt;2

【问题讨论】:

  • 很难理解为什么需要一个技巧,你循环 N / B 次,余数是 N % B。你通常把这个留给代码生成器,它已经知道如何展开循环。
  • 嗯,总是有 Duff's device 但你的代码没有问题。
  • 用 C 或任何语言?在某些汇编语言中,谓词指令可以很好地解决这个问题。
  • @Mike 我在想一些类似的事情。循环很短,因此余数的开销很大。
  • @harold C 是首选,但你可以举一些组装的例子吗?

标签: performance optimization


【解决方案1】:

您的if (N%2) 可以轻松扩展到任何展开因子:

for (; i < N-B+1; i += B) {
    x1; x2; ... xB;
}
if (i < N) {
    x1;
if (i < N-1) {
    x2;
    ...
if (i < N-B+2) {
    xB;
}}}

对于较小的展开因子,这可能比第二个循环或 Duff 的设备更有效。

这个版本看起来更好。 gcc 4.6 从中编译出几乎相同的代码:

if (i++ < N) {
    x1;
if (i++ < N) {
    x2;
    ...
if (i++ < N) {
    xB;
}}}

如果 B 是 2 的幂,这个版本可能会更理想。至少 gcc 为它编译了更好的代码。如果N 是一个常数,那绝对是最好的。但是如果N 既不是常数,B 也不是 2 的幂,则由于余数计算效率较低(这通常意味着多条指令,包括乘法),这种方法的优势就不那么明显了:

if (N%B > B-2) {
    x1;
if (N%B > B-3) {
    x2;
    ...
if (N%B > 0) {
    xB;
}}}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-28
    • 2016-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多