0

我有一个代码:

    if (Ly0 > 32767) {
        buffer[index] = 32767;
    } else if (Ly0 < -32768) {
        buffer[index] = -32768;
    } else {
        buffer[index] = (short) Ly0;
   }
  • buffer是短类型。
  • Ly0是浮点型。

我需要将浮点数转换为短,如果浮点数的整数部分大于短最大值短应该等于短最大值,并且如果浮点数的整数部分小于短最小值短应该等于短最小值,在其他情况下我需要将 float 转换为 short 并仅获取 float 的整数值。

换句话说,我需要从浮点数转换为短浮点数,如果浮点数超出短值范围,则截断浮点数。

问题是这种方法不够快速和持久。

将浮动转换为短的任何更快和最干净的方法。

4

3 回答 3

3

使用 sse 内在函数,您可以首先转换为整数,然后执行 long int 到 short int 饱和转换(使用PACKSSDW)。

一种“可移植”的方式是使用例如ORC,这是一个用于运行时编译的库,用于优化使用 mmx、sse、neon 和 avs 的内循环;以及提供兼容的串行实现。

甚至在此之前,可能需要检查编译器输出。例如。with gcc -ffast-math -O3 etc. 编译器通常可以生成已经 xmm 指令并并行化大型循环,其迭代次数在编译时是已知的。使用“luck == brute force”,可以将 c 代码调整为编译器可以识别饱和包模式的形式。通常它只取决于对中间计算类型的微观管理。(比较是有符号还是无符号,是 int 还是 short 等)

于 2012-12-23T09:48:00.800 回答
0

如果您有一个相当聪明的编译器,并且您实际上是在循环中执行此操作 - 并且假设您给编译器“优化它”的良好提示,那么它应该能够弄清楚您在做什么并使用“聪明”指令,例如 SSE/SSE2 - 当然,假设您正在编译的处理器支持它。

否则,使用编译器特定的扩展或内联汇编器将是您的选择——gcc 和 MS 编译器都具有执行此类操作的内在函数——或者,如建议的那样,可能有外部库可以很好地执行此操作。同样,假设处理器支持这种操作。

最后的建议,可能是这样做更快(在某些处理器上):

int x = Ly0;
if (x > 32767) x = 32767;
else if (x < -32768) x = -32768;
buffer[index] = (short)x; 

原因是浮点比较有时比整数比较昂贵 - 编译器可能会更好地优化此代码。但这并不能保证 - 一如既往地进行基准测试和比较。查看编译器输出并看看您是否认为它也有意义!

编辑:上面的代码假设这些值离您的预期范围不是很远。对于 40 亿以外的价值,它会出错。如果发生这种情况,那么无论如何您都需要使用浮点比较。

于 2012-12-23T10:03:27.193 回答
-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);
}
于 2012-12-23T09:45:30.407 回答