C 检查溢出的最快方法?
这是我的尝试。关于更好的解决方案有什么建议吗C 检查溢出的最快方法?,c,performance,optimization,embedded,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
// 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 );
}
我个人更喜欢使用SafeInt类进行溢出检查。它减少了繁琐的错误检查,并将其转化为易于处理但难以忽略的异常
我个人更喜欢使用SafeInt类进行溢出检查。它减少了繁琐的错误检查,并将其转化为易于处理但难以忽略的异常
你已经做的,是最快的可能为一个单一的演员。但是,您可以省略一些代码 溢出计数+=abssamps32[i]&0xFFFF8000?1 : 0; 可更改为: 如果samps32[i]&0xFFFF8000溢出计数++ 甚至更简单 如果samps32[i]>>15 overflowCount++ 这两个速度都一样快,而且都比你的快
如果你实际上在溢出计数中进行了交互,你可以考虑用SIMD操作处理整数数组。
你已经做的,对于一个单播来说最接近FistStist.但是,您可以省略一些代码
溢出计数+=abssamps32[i]&0xFFFF8000?1 : 0; 可更改为: 如果samps32[i]&0xFFFF8000溢出计数++ 甚至更简单 如果samps32[i]>>15 overflowCount++ 这两个速度都一样快,而且都比你的快如果您实际上在溢出计数中进行了交互,您可以考虑用SIMD操作处理整数数组。
位OPS也是我的选择。目前我能想象的唯一更快的方法是使用内联汇编,在其中加载源操作数,在芯片上制作副本,截断,并进行按位比较,这是伪伪代码
您的代码有一个问题:它违反了别名规则。您可以使用类似的方式: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);
}
编辑:根据你的编辑,你几乎使我的整个帖子无效。谢谢您在问题中没有提到您的编辑。位操作也是我的选择。目前我能想象的唯一更快的方法是使用内联汇编,在其中加载源操作数,在芯片上制作副本,截断,并进行按位比较,这是伪伪代码 您的代码有一个问题:它违反了别名规则。您可以使用类似的方式:
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);
}
编辑:根据你的编辑,你几乎使我的整个帖子无效。感谢您在问题中没有提到您的编辑。您似乎正在检查16位加法是否溢出。您可以通过使用
overflowCount += (samps32[i] & 0x8000) >> 15;
这将生成三个ALU操作,但代码中没有分支。它可能比分支版本快,也可能不快。您似乎正在检查16位加法是否溢出。您可以通过使用
overflowCount += (samps32[i] & 0x8000) >> 15;
这将生成三个ALU操作,但代码中没有分支。它可能比分支版本快,也可能不快。我们正在将int32\u t转换为int16\u t。只想提一句:根据您的编辑,您几乎使我的整个帖子无效。感谢您在问题中没有提到您的编辑。由于您的编辑混乱且毫无帮助,因此被否决。Phresnel您在我编辑问题时给出了答案。我们正在将int32_t转换为int16_t。只想提及:根据您的编辑,您几乎使我的整个帖子无效。谢谢你在问题中没有提到你的编辑。因为你的编辑混乱且没有帮助,所以被否决了。Phresnel你在我编辑问题时给出了答案。他们不一定更快。OP的三元操作非常简单,编译器可以将其优化为条件移动,这两种方法都可以。即使没有可用的cmove,由于条件分支,您的代码仍可能执行得更差。。。。。。然而,三元运算更容易转换为查找表查找。不需要条件分支,编译器可以使用setz等指令。phresnel它们更快的原因不仅是因为使用了简写的条件表达式,还因为取消了对abs的调用,使用递增而不是加法。而且使用查找表将是一个巨大的开销,它们不一定更快。OP的三元操作非常简单,编译器可以将其优化为条件移动,这两种方法都可以。即使没有可用的cmove,由于条件分支,您的代码仍可能执行得更差。。。。。。然而三元运算更容易转换为查找表。不需要条件分支,编译器可以使用setz等指令。phresnel它们更快的原因不仅仅是 因为简写的条件表达式,但是因为对abs的调用已经被删除,并且使用递增而不是加法。使用查找表将是一个巨大的开销。