检查溢出的最快方法?

发布于 2024-07-15 09:04:01 字数 769 浏览 4 评论 0原文

这是我的尝试。 关于更好的解决方案有什么建议吗?:

// 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; 

Here's my attempt. Any tips on a better solution?:

// 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 );
}

Here's the part that actually checks for overflow:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

手长情犹 2024-07-22 09:04:01

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

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

I personally prefer to use the SafeInt class to do my overflow checking. It reduces the need for tedious error checking and turns it into an easy to process, yet difficult to ignore exception.

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

偷得浮生 2024-07-22 09:04:01

您已经做的事情最接近单次施法的最快速度。 但是你可以省略一些代码

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

可以改为:

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

甚至更简单

if(samps32[i]>>15)overflowCount++;

这两个都同样快,并且都比你的更快。

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

What you already do, is closest to the fastests possible for a single cast. you can however omit some code

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

can be changed into:

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

or even simpler

if (samps32[i] >> 15) overflowCount++;

both of these will be equally fast, and both will be faster than yours.

If you are actually interrested in the count of overflows, you might consider processing the array of integers with SIMD operations.

老旧海报 2024-07-22 09:04:01

您似乎正在检查 16 位加法是否溢出。 分支来避免汇编代码中的分支

overflowCount += (samps32[i] & 0x8000) >> 15;

您可以通过仅使This 生成三个 ALU 操作但在代码中不产生 。 它可能比分支版本快,也可能不快。

It seems that you are checking for the overflow of a 16-bit addition. You can avoid branch in the assembler code by just having

overflowCount += (samps32[i] & 0x8000) >> 15;

This generates three ALU operations but no branch in the code. It may or may not be faster than a branching version.

不寐倦长更 2024-07-22 09:04:01

位操作也是我的选择。 目前我能想到的唯一更快的方法是使用内联汇编,在其中加载源操作数,在芯片上进行复制,截断和按位比较(这是伪伪代码)。

您的代码有一个问题:它违反了别名规则。 您可以使用类似这样的内容:

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);
}

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

Bit ops would be my choice, too. the only faster way I can imagine at the moment is to use inline assembly where you load the source operand, make a copy onboard the chip, truncate, and bitwise compare (that was pseudo pseudo code).

Your code has an issue: It violates aliasing rules. You could use something like this instead:

union conv_t {
    int32_t i32;
    int16_t i16;
};

Then you could ensure that IQBuffer is of that type. Finally, you could run:

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

edit: As per your edit (https://stackoverflow.com/revisions/677427/list) you drove nearly my whole post invalid. Thanks for not mentioning your edit in your question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文