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



我处于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

无论如何?为了更快的缓存/管道...

如果您只是从另一个原始值中扣除一个原始值,那么您的答案可能会更准确、更快,然后对此进行 mults/div。 例如:

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

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

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

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

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

假设允许浮点系数,您可以预先计算d:= b / c并计算round(a * d) * c,从而节省昂贵的除法。

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

最新更新