性能:float 到 int 转换并将结果裁剪到范围

2024-04-09

我正在用 float 进行一些音频处理。结果需要转换回 PCM 样本,并且我注意到从 float 到 int 的转换非常昂贵。 更令人沮丧的是,我需要将结果限制在短路范围内(-32768 到 32767)。 虽然我通常本能地假设可以通过简单地将 float 转换为 Short 来确保这一点,但在 Java 中这会严重失败,因为在字节码级别上它会导致 F2I 后跟 I2S。所以而不是简单的:

int sample = (short) flotVal;

我需要诉诸这个丑陋的序列:

int sample = (int) floatVal;
if (sample > 32767) {
    sample = 32767;
} else if (sample < -32768) {
    sample = -32768;
}

有没有更快的方法来做到这一点?

(大约总运行时间的 6% 似乎花费在转换上,而 6% 乍一看似乎并没有那么多,当我考虑到处理部分涉及大量矩阵乘法和 IDCT 时,这是令人震惊的)

  • 编辑上面的转换/剪切代码(毫不奇怪)位于循环体中,该循环体从 float[] 读取浮点值并将它们放入 byte[] 中。我有一个测试套件,可以测量几个测试用例的总运行时间(处理大约 200MB 的原始音频数据)。 6% 是通过将循环索引分配给样本来替换转换分配“int sample = (int) floatVal”时的运行时差异得出的。

  • 编辑@leopoldkot:我知道Java中的截断,如原始问题(F2I,I2S字节码序列)中所述。我只尝试了短转换,因为我假设 Java 有 F2S 字节码,但不幸的是它没有(最初来自 68K 程序集背景,其中简单的“fmove.w FP0, D0”就可以完全满足我的要求) 。


对于范围内的值,您可以将两次比较转换为一次比较。这可以使成本减半。目前,如果该值太负,则仅执行一次比较。 (这可能不是您的典型案例)

if (sample + 0x7fff8000 < 0x7fff0000)
    sample = sample < 0 ? -32768 : 32767;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

性能:float 到 int 转换并将结果裁剪到范围 的相关文章

随机推荐