最近,我在使用一个类似于以下代码的应用程序:
for (auto x = 0; x < width - 1 - left; ++x)
{
// store / reset points
temp = hPoint = 0;
for(int channel = 0; channel < audioData.size(); channel++)
{
if (peakmode) /* fir rms of window size */
{
for (int z = 0; z < sizeFactor; z++)
{
temp += audioData[channel][x * sizeFactor + z + offset];
}
hPoint += temp / sizeFactor;
}
else /* highest sample in window */
{
for (int z = 0; z < sizeFactor; z++)
{
temp = audioData[channel][x * sizeFactor + z + offset];
if (std::fabs(temp) > std::fabs(hPoint))
hPoint = temp;
}
}
.. some other code
}
... some more code
}
这是在一个图形渲染循环中,以每秒50-100次的频率调用,在多个通道上具有高达192kHz的缓冲区。因此,大量数据通过最内部的循环运行,并且分析表明这是一个热点。
我想到可以将浮点数转换为整数并擦除符号位,然后仅使用临时变量将其转换回来。看起来类似于这样:
if ((const float &&)(*((int *)&temp) & ~0x80000000) > (const float &&)(*((int *)&hPoint) & ~0x80000000))
hPoint = temp;
这样做可以将渲染时间缩短12倍,同时仍然产生相同且有效的输出。请注意,audiodata中的所有内容都经过处理以不包含NaNs/Infs/Denormals,并且仅具有[-1,1]的范围。
是否存在任何角落案例会导致此优化出现错误结果,或者为什么标准库函数没有像这样实现?我猜想这与处理非正常值有关?
e:浮点模型的布局符合IEEE标准,并且sizeof(float)== sizeof(int)== 4