这是我的尝试。关于更好的解决方案的任何提示?:
// 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;
答案 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),您几乎将我的整个帖子视为无效。谢谢你没有在你的问题中提及你的编辑。