【发布时间】:2016-05-06 14:41:46
【问题描述】:
- 我需要将一些值从数组 A 复制到数组 B。
- 要复制的项目数存储在 uint32_t r3 变量中。
- 从 a 复制到 b 的值的每个索引都编码在 uint32_t next 变量中。
- 每个索引不能超过 255(8 位),因此 4 个索引被编码到 uint32_t 变量 ip 中,并使用 OPCODE_GET_FOUR8bit 宏进行解码。
使用宏 STACK_GET(index) 从数组 A 读取数据,并使用宏 SETVALUE(index, value) 将数据写入数组 B。
我当前的复制循环是:
register uint32_t nloop = (r3+3)>>2; // efficient way to round r/4 upward
register idx = 0;
while (nloop) {
uint32_t next = *ip++;
OPCODE_GET_FOUR8bit(next, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4);
if (r3) { SETVALUE(rwin+idx, STACK_GET(p1)); --r3;
if (r3) { SETVALUE(rwin+idx+1, STACK_GET(p2)); --r3;
if (r3) { SETVALUE(rwin+idx+2, STACK_GET(p3)); --r3;
if (r3) { SETVALUE(rwin+idx+3, STACK_GET(p4)); --r3;
}
}
}
}
--nloop; idx+=4;
}
这涉及循环内的 4 个 r3 递减和 4 个 if 语句(因为我事先知道使用 r3 复制的项目数,但循环一次编码 4 个索引)。
我想知道是否有办法加快这个性能关键循环。
【问题讨论】:
-
只是评论,不是答案:不要四舍五入,只是截断 (r3>>2)。然后在不测试 r3 的情况下执行所有循环,因为您知道它将大于 0。然后,在循环之后,执行剩余的 3 个 r3 测试。这样,您将在每个循环中节省 4 个 if。也不要做--r3,只在每次迭代结束时做 r3-=4
-
所有这些宏有什么作用?如果有任何事情甚至有点不重要,那么它们很可能是限速步骤。你能告诉我们为什么
memcpy不适合这个吗? -
例如,当 r3 为 2 时,nloop 为 1 并且 ip 将包含 2 个索引和 2 个垃圾编码,这就是为什么我需要在循环内递减并检查 r3 4 次,否则为 2垃圾会被复制。
-
memcpy 不适合,因为 p1,p2,p3,p4 可以是非连续索引。
标签: c arrays performance macros