c++ - 你将如何优化这个矢量化的谐波总和?
问题描述
我正在使用矢量化(仅 SSE2 max 作为 SIMD)将一组谐波相加,每个谐波具有不同的相位/幅度。
这是我的实际尝试:
float output = 0.0f;
simd::float_4 freqFundamentalNormalized = freq * (1.0f / sampleRate);
simd::float_4 harmonicIndex{1.0f, 2.0f, 3.0f, 4.0f};
simd::float_4 harmonicIncrement{4.0f, 4.0f, 4.0f, 4.0f};
// harmonics
const int numHarmonicsV4 = numHarmonics / 4;
const int numHarmonicsRemainder = numHarmonics - (numHarmonicsV4 * 4);
// v4
for (int i = 0; i < numHarmonicsV4; i++) {
// signal
simd::float_4 sineOutput4 = simd::sin(mPhases4[i] * g2PIf) * mMagnitudes4[i];
for (int v = 0; v < 4; v++) {
output += sineOutput4[v];
}
// increments
mPhases4[i] += harmonicIndex * freqFundamentalNormalized;
mPhases4[i] -= simd::floor(mPhases4[i]);
harmonicIndex += harmonicIncrement;
}
// remainder
if (numHarmonicsRemainder > 0) {
// signal
simd::float_4 sineOutput4 = simd::sin(mPhases4[numHarmonicsV4] * g2PIf) * mMagnitudes4[numHarmonicsV4];
for (int v = 0; v < numHarmonicsRemainder; v++) {
output += sineOutput4[v];
}
// increments
mPhases4[numHarmonicsV4] += harmonicIndex * freqFundamentalNormalized;
mPhases4[numHarmonicsV4] -= simd::floor(mPhases4[numHarmonicsV4]);
}
但:
- 我想我可以更多地优化它,也许用一些数学技巧,或者以一些增量保存
- 我不喜欢重复“相同的代码”一次
V4
,一次remainder
(如果谐波数不是 % 4):有没有办法在最后的 V4 放置中放置一种“掩码”(例如)幅度为 0?(所以它在同一个块中执行相同的操作,但不会汇总到最终输出)。
解决方案
问题的第二部分是最简单的。幅度为 0 的任何谐波都不会影响正弦输出,因此您只需填充mMagnitude
为 4 的倍数。
正如 Damien 指出的那样,sin(x)
价格昂贵。但由欧拉exp(x)=cos(x) + i sin(x)
,和exp(x+dx)==exp(x)*exp(dx)
。每一步都只是一个复杂的乘法。
推荐阅读
- mysql - MySQL GRANT 被接受但未应用
- flutter - Flutter inday 中的 Null 检查错误
- planning - 推箱子的 PDDL 规划师,挑战
- scala - 如何使用 Scala 在 CSV 中找出字符串并将其替换为嵌套数组
- python - 界面拉伸时的一些问题
- google-analytics - 有没有办法确定导致用户放弃 GoogleAnalytics/Data Studio 中应用程序内部旅程的原因?
- html - 将文本固定在一行 - 菜单 CSS 中的移动幻灯片
- python - 尝试安装 scikit-learn 显示 comman exit out with error status 1
- r - 如何使用 R 在我的收件箱中检索 Outlook 电子邮件的正文?
- c# - 将继承类的对象转换为继承类型的实例