性能:浮点到int转换和裁剪结果到范围 [英] Performance: float to int cast and clipping result to range

查看:247
本文介绍了性能:浮点到int转换和裁剪结果到范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用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;





$是有更快的方法来做到这一点吗?$ b $ (大约6%的运行时间似乎花费在铸造上,而6%似乎乍看起来不算什么,当我认为处理部分涉及到一个好块矩阵乘法和IDCT)


  • 上面的cast / clipping代码在循环体中是(不奇怪)从float []中读取浮点值并将其放入byte []中。我有一个测试套件,可以测试多个测试用例的总运行时间(处理大约200MB的原始音频数据)。当通过将循环索引分配给样本来替换投影赋值int sample =(int)floatVal时,从运行时差异中得出6%的结论。

  • 编辑@leopoldkot:我知道Java中的截断,如原始问题(F2I,I2S字节码序列)所述。我只是试图简化,因为我认为Java有一个F2S字节码,这不幸的是(原来从一个68K大会背景,其中一个简单的fmove.w FP0,D0将完成我想要的) 。

    解决方案

    您可以将两个比较合并为一个范围。这可能会使成本减半。目前,如果值太负,则只执行一次比较。 (这可能不是你的典型案例)

    $ p $ if(sample + 0x7fff8000< 0x7fff0000)
    sample = sample< ; 0? -32768:32767;


I'm doing some audio processing with float. The result needs to be converted back to PCM samples, and I noticed that the cast from float to int is surprisingly expensive. Whats furthermore frustrating that I need to clip the result to the range of a short (-32768 to 32767). While I would normally instictively assume that this could be assured by simply casting float to short, this fails miserably in Java, since on the bytecode level it results in F2I followed by I2S. So instead of a simple:

int sample = (short) flotVal;

I needed to resort to this ugly sequence:

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

Is there a faster way to do this?

(about ~6% of the total runtime seems to be spent on casting, while 6% seem to be not that much at first glance, its astounding when I consider that the processing part involves a good chunk of matrix multiplications and IDCT)

  • EDIT The cast/clipping code above is (not surprisingly) in the body of a loop that reads float values from a float[] and puts them into a byte[]. I have a test suite that measures total runtime on several test cases (processing about 200MB of raw audio data). The 6% were concluded from the runtime difference when the cast assignment "int sample = (int) floatVal" was replaced by assigning the loop index to sample.

  • EDIT @leopoldkot: I'm aware of the truncation in Java, as stated in the original question (F2I, I2S bytecode sequence). I only tried the cast to short because I assumed that Java had an F2S bytecode, which it unfortunately does not (comming originally from an 68K assembly background, where a simple "fmove.w FP0, D0" would have done exactly what I wanted).

解决方案

You could turn two comparisons into one for values which are in range. This could halve the cost. Currently you perform only one comparison if the value is too negative. (which might not be your typical case)

if (sample + 0x7fff8000 < 0x7fff0000)
    sample = sample < 0 ? -32768 : 32767;

这篇关于性能:浮点到int转换和裁剪结果到范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆