我在 32 位 Tensilica Xtensa DSP 微控制器上运行相对简单的 64 位重型算法,分析显示我们花费了很大一部分时间在两个 32 位 CPU 上执行基本的 64 位操作64 位变量的寄存器。
for(uint64_t bit = 1; bit; bit<<=1){
if(bit & aGlobalBit){
//Some light math
} else {
//different light math
}
}
将上述伪代码稀疏展开两次,分别覆盖位索引 0->31 和 32->63,显示出很大的运行时加速。反汇编显示每个循环的指令数量大幅减少,因为 GCC12 发现每个循环只使用了 uint64_t 的一半:
//Do32LSBs
for(uint32_t bit = 1; bit; bit<<=1){
if(bit & aGlobalBit){
//Some light math
} else {
//different light math
}
}
//Do32MSBs
for(uint32_t bitMsb = 1; bitMsb; bitMsb<<=1){
uint64_t bit = (uint64_t)bitMsb << 32;
if(bit & aGlobalBit){
//Some light math
} else {
//different light math
}
}
但我想找到一种更简洁的方法来做到这一点 - 迭代 uint64_t 中的位被大量使用,并且加速不值得维护循环体的两个副本。我已经阅读了 GCC 编译器手册中有关内联的部分,并且没有一个选项可以稀疏地执行此操作。如何抽象地包装位迭代,以便我可以编写一次并将其与 for-auto-x 一起使用?如果没有,是否有另一种方法可以从循环体中抽象迭代,同时仍然允许每个 uint64_t 一次进行 32 位迭代?
老兄,这些只有 64 个值,只需将它们放入数组即可。它的大小为 512 字节,我相信您会在这个 MCU 资源中找到它们。