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

C++ 我可以进一步简化此代码/表达式吗?,c++,caching,math,optimization,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) / gBlockS

我在一个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

有办法吗?为了更快地缓存/管道…

如果您只是从另一个原始值中扣除一个,然后对其执行mult/div,您的答案可能会更准确、更快。e、 g:

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,因为无符号整数表示您只关心/处理非负数。所以你可以把事情简化为:

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

上面的代码假设gBlockSize为int,如果不是,则使用fmodposFinal、gBlockSize而不是posFinal%gBlockSize

假设允许使用浮点系数,您可以预计算d:=b/c并计算rounda*d*c,这样就省去了一个昂贵的除法


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

您是否测量了您的程序以确认上述代码是否是性能瓶颈?如果gBlockSize是2的幂,则可以执行shift>>而不是除法。在这两种情况下,您似乎都是在乘以gBlockSize。也许你可以把这两个乘法取出来,然后把posFinal相乘。这将为您节省一次乘法运算。虽然不多,但总比什么都没有好。请随时问这样的问题。一定要符合那里的政策。有什么办法吗?要加快缓存/管道…-虽然我不知道你们的DSP平台;今天的CPU比以往任何时候都要复杂。我不是这方面的专家,但今天,我怀疑是否有可能准确预测程序的缓存和管道顺序,以及所有无序执行等。您所能做的最好的事情就是使用程序中的热点并使其真正对缓存友好,仅举几个可能影响性能的旋钮