我有一个代码:
if (Ly0 > 32767) {
buffer[index] = 32767;
} else if (Ly0 < -32768) {
buffer[index] = -32768;
} else {
buffer[index] = (short) Ly0;
}
buffer
是短类型。Ly0
是浮动类型。我需要将float转换为short,如果float的整数部分超过short short short short应该等于short short value,并且如果float的整数部分小于short short short short应该等于short min value,在其他我需要将float转换为short并获得float的整数值。
换句话说,我需要从float转换为short并截断float,如果它超出了short的范围。
问题是这种方法并不快,而且很快。
是否有任何更快,更干净的方式将float转换为short。
答案 0 :(得分:3)
使用sse内在函数,您可以先转换为整数,然后执行long int到short int饱和转换(使用PACKSSDW)。
“便携式”方式是使用例如ORC,这是一个运行时编译库,用于优化内环,使用mmx,sse,neon和avs;以及提供兼容的串行实现。
甚至在此之前,可能需要检查编译器输出。例如。对于gcc -ffast-math -O3
等,编译器通常可以生成已经xmm的指令并并行化大循环,其迭代计数在编译时是已知的。使用“luck == brute force”,可以将c代码调整为编译器可以识别饱和包模式的形式。通常它只取决于微观管理中间计算的类型。 (是比较有符号还是无符号,是int还是short等。)
答案 1 :(得分:0)
如果你有一个相当明亮的编译器,并且你实际上是在循环中这样做 - 假设你给编译器一个很好的“优化这个”的提示,那么它应该能够弄清楚你在做什么和使用“聪明”的指令,例如SSE / SSE2 - 假设你正在编译的处理器支持它,当然。
否则,使用编译器特定扩展或内联汇编程序将是您的选择 - gcc和MS编译器都具有执行此类操作的内部函数 - 或者,如建议的那样,可能有外部库可以很好地执行此操作。再次,假设有这种操作的处理器支持。
最后一个建议,可能是这样做(在某些处理器上)更快:
int x = Ly0;
if (x > 32767) x = 32767;
else if (x < -32768) x = -32768;
buffer[index] = (short)x;
原因是浮点比较有时比整数更昂贵 - 并且编译器可以更好地优化此代码。但这并不能保证 - 一如既往地基准和比较。查看编译器输出并看看你认为它是否有意义永远不会伤害!
编辑:上面的代码假定这些值与您的预期范围相差不远。对于40亿以外的价值,它会出错。如果发生这种情况,那么无论如何都需要使用浮点比较。
答案 2 :(得分:-2)
可能没有办法优化代码的和平。我猜这个代码在一些周期内执行很多次,因为你有性能问题。您需要考虑优化周期。例如,如果Ly0值在随机访问容器中,则优化后可能会产生良好的结果。
for (int index = 0; index < (Ly0s.size() - 4); idx += 4) {
do_conversion_for(index);
do_conversion_for(index + 1);
do_conversion_for(index + 2);
do_conversion_for(index + 3);
}
switch (Ly0s.size() % 4){
case 3:
do_conversion_for(index + 3);
case 2:
do_conversion_for(index + 2);
case 1:
do_conversion_for(index + 1);
}
而不是
for (int index = 0; index < Ly0s.size(); ++idx) {
do_conversion_for(index);
}