小编Luí*_*ier的帖子

为什么uint_least16_t比uint_fast16_t快于x86_64中的乘法?

关于uint_fast*_t类型族,C标准还不太清楚.在gcc-4.4.4 linux x86_64系统上,类型uint_fast16_tuint_fast32_t大小均为8个字节.但是,8字节数的乘法似乎比4字节数的乘法慢得多.以下代码演示了:

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int
main ()
{
  uint_least16_t p, x;
  int count;

  p = 1;
  for (count = 100000; count != 0; --count)
    for (x = 1; x != 50000; ++x)
      p*= x;

  printf("%"PRIuLEAST16, p);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到了在程序上运行time命令

real 0m7.606s
user 0m7.557s
sys  0m0.019s
Run Code Online (Sandbox Code Playgroud)

如果我将类型更改为uint_fast16_t(和printf修饰符),则时间变为

real 0m12.609s
user 0m12.593s
sys  0m0.009s
Run Code Online (Sandbox Code Playgroud)

那么,如果stdint.h头文件uint_fast16_t(以及uint_fast32_t)定义为4字节类型,那会不会更好?

c unsigned x86-64 multiplication

11
推荐指数
2
解决办法
2983
查看次数

GCC热点?

当我编译这段代码时

unsigned char A[] = {1, 2, 3, 4};

unsigned int
f (unsigned int x)
{
  return A[x];
}
Run Code Online (Sandbox Code Playgroud)

gcc输出

mov edi, edi
movzx  eax, BYTE PTR A[rdi]
ret
Run Code Online (Sandbox Code Playgroud)

在x86_64机器上.

问题是:为什么有nop指令(mov edi,edi)?

我正在使用gcc-4.4.4.

c assembly gcc

5
推荐指数
1
解决办法
787
查看次数

C中的无符号溢出

考虑以下C代码:

#include <stdint.h>

uint32_t inc(uint16_t x) {
 return x+1;
}
Run Code Online (Sandbox Code Playgroud)

当使用gcc-4.4.3在纯x86_64系统上使用标志-std = c99 -march = core2 -msse4.1 -O2 -pipe -Wall进行编译时,它会生成

movzwl %di,%eax
inc    %eax
retq
Run Code Online (Sandbox Code Playgroud)

现在,在C中预测无符号溢出.我不太了解x86_64汇编,但据我所知,16位参数寄存器被移动到32位寄存器,该寄存器递增并返回.我的问题是,如果x == UINT16_MAX怎么办.会发生溢出,标准规定x + 1 == 0,对吗?但是,如果%eax是一个32位寄存器,它现在包含UINT16_MAX + 1,这是不正确的.

这让我在这里连接一个问题:是否有一种可移植的方法来禁用C中的无符号溢出,以便编译器可以假设存储在大寄存器中的小变量的高位始终为0(所以它不需要清除它们)?如果不是(或者如果解决方案在语法上是令人讨厌的),至少在GCC中有没有办法做到这一点?

非常感谢您的宝贵时间.

c int assembly unsigned overflow

4
推荐指数
1
解决办法
755
查看次数

标签 统计

c ×3

assembly ×2

unsigned ×2

gcc ×1

int ×1

multiplication ×1

overflow ×1

x86-64 ×1