相关疑难解决方法(0)

我可以通过给出整数范围来提示优化器吗?

我正在使用一种int类型来存储一个值.根据程序的语义,值总是在很小的范围内变化(0 - 36),并且仅使用int(不是a char)因为CPU效率.

似乎可以在如此小的整数范围内执行许多特殊的算术优化.可以将对这些整数的许多函数调用优化为一小组"神奇"操作,并且甚至可以将某些函数优化为表查找.

那么,是否有可能告诉编译器这int总是在那么小的范围内,并且编译器是否可以进行这些优化?

c++ optimization integer range compiler-optimization

171
推荐指数
4
解决办法
6910
查看次数

除非Haswell指定,否则GCC会很难编制前导零计数

GCC支持__builtin_clz(int x)内置,它计算参数中前导零(连续最重要的零)的数量.

除了其他东西0之外,这对于有效地实现lg(unsigned int x)函数非常有用,该函数采用基数2的对数x,舍入为1:

/** return the base-2 log of x, where x > 0 */
unsigned lg(unsigned x) {
  return 31U - (unsigned)__builtin_clz(x);
}
Run Code Online (Sandbox Code Playgroud)

这部作品在简单的方式-尤其是考虑的情况下x == 1,并clz(x) == 31-再x == 2^0这样lg(x) == 031 - 31 == 0我们得到正确的结果.更高的x工作价值.

假设内置程序有效实现,这比备用纯C解决方案更好.

现在,它发生了,计数前导零操作基本上是bsrx86中指令的双重.返回参数中最重要的1位2的索引.因此,如果有10个前导零,则第一个1位位于参数的第21位.一般来说,我们有31 - clz(x) == bsr(x),并在这样bsr …

c performance x86 gcc intel

9
推荐指数
1
解决办法
668
查看次数

在x86-64 SysV ABI中,高位参数和返回值寄存器是否允许垃圾?

除了其他方面,x86-64 SysV ABI指定了如何在寄存器中传递函数参数(第一个参数in rdi,then rsi等等),以及如何传回整数返回值(in rax和then rdx表示非常大的值).

然而,我找不到的是当传递小于64位的类型时,参数或返回值寄存器的高位应该是什么.

例如,对于以下功能:

void foo(unsigned x, unsigned y);
Run Code Online (Sandbox Code Playgroud)

... x将被传入rdiyrsi,但他们只是32位.不要的高32位rdirsi必须为零?直观地说,我会假设是,但是所有gcc,clang和icc 生成代码mov在开始时都有特定的指令将高位清零,所以看起来编译器假定不然.

类似地,编译器似乎假设rax如果返回值小于64 位,则返回值的高位可能具有垃圾位.例如,以下代码中的循环:

unsigned gives32();
unsigned short gives16();

long sum32_64() {
  long total = 0;
  for (int i=1000; i--; ) {
    total += gives32();
  }
  return total;
}

long sum16_64() {
  long total = 0;
  for (int i=1000; i--; ) {
    total += …
Run Code Online (Sandbox Code Playgroud)

linux x86 x86-64 calling-convention

8
推荐指数
1
解决办法
403
查看次数

从/向xmm/ymm寄存器加载/存储通用寄存器的最佳方法

从SIMD寄存器加载和存储生成目的寄存器的最佳方法是什么?到目前为止,我一直在使用堆栈作为临时.例如,

mov [rsp + 0x00], r8
mov [rsp + 0x08], r9
mov [rsp + 0x10], r10
mov [rsp + 0x18], r11
vmovdqa ymm0, [rsp] ; stack is properly aligned first.
Run Code Online (Sandbox Code Playgroud)

我认为没有任何指令可以直接(或另一个方向)执行此操作,因为它意味着具有五个操作数的指令.但是,上面的代码对我来说似乎很愚蠢.有没有更好的方法呢?我只能想到一个替代方案,使用pinsrd相关说明.但它似乎没有任何好转.

动机是,有时候在AVX2中做一些事情会更快,而其他用于通用的注册事项.例如,在一小段代码中,有四个64位无符号整数,我将需要四个xor,两个mulx来自BMI2.这将是更快的做xorvpxor,但是,mulx没有一个AVX2等同.由于包装和拆包过程,任何vpxor对比4 的增益xor都会丢失.

x86 assembly simd sse2 avx2

7
推荐指数
1
解决办法
783
查看次数