检查溢出的最快方法?

时间:2009-03-24 13:36:03

标签: c performance optimization embedded

这是我的尝试。关于更好的解决方案的任何提示?:

// for loop to convert 32 to 16 bits
uint32_t i;
int32_t * samps32 = (int32_t *)&(inIQbuffer[0]);
int16_t * samps16 = (int16_t *)&(outIQbuffer[0]);
for( i = 0; i < ( num_samples * 2/* because each sample is two int32 s*/ ); i++ ) {
    overflowCount += ( abs(samps32[i]) & 0xFFFF8000 ) ? 1 : 0; 
    samps16[i] = (int16_t)samps32[i];
}

// Only report error every 4096 accumulated overflows
if( ( overflowCount & 0x1FFF ) > 4096 ) {
    printf( "ERROR: Overflow has occured while scaling from 32 "
            "bit to 16 bit samples %d times", 
            overflowCount );
}

这是实际检查溢出的部分:

overflowCount += ( abs(samps32[i]) & 0xFFFF8000 ) ? 1 : 0; 

4 个答案:

答案 0 :(得分:3)

我个人更喜欢使用SafeInt类来进行溢出检查。它减少了繁琐的错误检查的需要,并将其转换为易于处理但难以忽略的异常。

http://blogs.msdn.com/david_leblanc/archive/2008/09/30/safeint-3-on-codeplex.aspx

答案 1 :(得分:2)

你已经做过的,最接近单人演员的紧固件。但是你可以省略一些代码

  

overflowCount + =(abs(samps32 [i])&amp; 0xFFFF8000)? 1:0;

可以改为:

  

if(samps32 [i]&amp; 0xFFFF8000)overflowCount ++;

甚至更简单

  

if(samps32 [i]&gt;&gt; 15)overflowCount ++;

这两个都同样快,两者都会比你的快。

如果您确实对溢出计数感兴趣,可以考虑使用SIMD操作处理整数数组。

答案 2 :(得分:1)

似乎您正在检查16位加法的溢出。只需要

就可以避免汇编代码中的分支
overflowCount += (samps32[i] & 0x8000) >> 15;

这会生成三个ALU操作,但代码中没有分支。它可能比分支版本更快也可能没有。

答案 3 :(得分:0)

比特操作也是我的选择。我现在能想象的唯一更快的方法是使用内联汇编来加载源操作数,在芯片上复制,截断和逐位比较(这是伪伪代码)。

您的代码存在问题:它违反了别名规则。你可以使用这样的东西:

union conv_t {
    int32_t i32;
    int16_t i16;
};

然后你可以确保IQBuffer属于那种类型。最后,你可以运行:

for( i = 0; i < (num_samples * 2); i++ ) {
    <test goes here>
    samps [i].i16 = static_cast<int16_t>(samps [i].i32);
}

修改:根据您的修改(https://stackoverflow.com/revisions/677427/list),您几乎将我的整个帖子视为无效。谢谢你没有在你的问题中提及你的编辑。