我可以进一步简化此代码/表达式吗?

时间:2017-05-22 11:07:55

标签: c++ caching math optimization

我在DSP环境中,我需要加快一些操作。

这是我的公式,经常执行:

unsigned int pos0 = (unsigned int)round((envelope.mLengths[sectionIndex] * mSampleRate) / gBlockSize) * gBlockSize;
unsigned int pos1 = (unsigned int)round((envelope.mLengths[sectionIndex + 1] * mSampleRate) / gBlockSize) * gBlockSize;
unsigned int posFinal = pos1 - pos0;

基本上,我想简化的是这个数学公式:

round((a * b) / c) * c

任何方式?为了更快的缓存/管道...

2 个答案:

答案 0 :(得分:2)

如果您只是从另一个中扣除一个原始值,那么您的答案可能会更准确,更快,然后就可以使用mults / divs。 e.g:

auto posRaw = envelope.mLengths[sectionIndex + 1] - envelope.mLengths[sectionIndex];
auto posFinal = (unsigned int)round(posRaw  * mSampleRate) / gBlockSize) * gBlockSize;

通过更早地舍入会得到更多的舍入错误,这取决于这些是否是故意的。上面的代码只对原始值进行减法,然后在结尾处进行一次舍入。但是YMMV因为根据输入会产生略微不同的结果。如果轻微的舍入差异无关紧要(因为我怀疑他们没有),那么最后将所有内容都整理一次。

此外,您要除以gBlockSize,删除任何分数,然后乘以gBlocksize并转换为(unsigned int)。这与从val中减去(val%gBlockSize)相同。你可以用整数模数(%)来做到这一点(你不必担心负值可能会搞乱mod,因为unsigned int表示你只关心/处理非负数)。所以你可以简化这个:

unsigned int posFinal = (envelope.mLengths[sectionIndex + 1] - envelope.mLengths[sectionIndex]) * mSampleRate;
posFinal -= posFinal % gBlockSize;

上面的代码假设gBlockSize是int,如果没有,请使用fmod(posFinal,gBlockSize)而不是posFinal%gBlockSize

答案 1 :(得分:1)

假设允许使用浮点系数,您可以预先计算d:= b / c并评估round(a * d) * c,这可以节省高成本。

此外,如果必须计算所有索引的增量,则应一次评估一个值并保留下一次迭代的副本。这将节省近一半的工作。