小编Ber*_*ach的帖子

为什么这一系列指令更快?

我正在比较GCC和Clang输出来评估浮点表达式,并偶然发现了我无法解释的性能差异.

源代码

float evaluate(float a, float b) {
    return (a - b + 1.0f) * (a - b) * (a - b - 1.0f);
}
Run Code Online (Sandbox Code Playgroud)

产生GCC 7.2(-std = c ++ 1y -O2)

evaluate(float, float):
  subss xmm0, xmm1
  movss xmm2, DWORD PTR .LC0[rip]
  movaps xmm1, xmm0
  addss xmm1, xmm2
  mulss xmm1, xmm0
  subss xmm0, xmm2
  mulss xmm0, xmm1
  ret
.LC0:
  .long 1065353216
Run Code Online (Sandbox Code Playgroud)

而Clang 5.0.0(-std = c ++ 1y -O2)产生了

.LCPI0_0:
  .long 1065353216 # float 1
.LCPI0_1:
  .long 3212836864 # float -1 …
Run Code Online (Sandbox Code Playgroud)

c++ x86 assembly gcc clang

12
推荐指数
0
解决办法
390
查看次数

为什么 GCC 会发出重复的 `ret`?

在下面的 C++ 示例中,我定义了一个计算树最左边路径高度的函数。

struct TreeNode {
  int value{};
  TreeNode *l = nullptr;
  TreeNode *r = nullptr;
};

int getLeftHeight(TreeNode *root) {
  int height = 0;
  while (root != nullptr) {
    root = root->l;
    height++;
  }
  return height;
}
Run Code Online (Sandbox Code Playgroud)

使用 GCC 9.3 或 10.1(使用 -O3)编译时,我得到以下 x86。

getLeftHeight(TreeNode*):
        xor     eax, eax
        test    rdi, rdi
        je      .L4
.L3:
        mov     rdi, QWORD PTR [rdi+8]
        add     eax, 1
        test    rdi, rdi
        jne     .L3
        ret
.L4:
        ret
Run Code Online (Sandbox Code Playgroud)

但是,在使用 Clang 10 编译时,如下图所示,没有重复的ret.

getLeftHeight(TreeNode*):
        xor     eax, …
Run Code Online (Sandbox Code Playgroud)

c++ x86 gcc clang

6
推荐指数
1
解决办法
130
查看次数

为什么GCC不报告未初始化的变量?

#include <ios>
#include <iostream>
#include <map>

using namespace std;

int main() {
  ios_base::sync_with_stdio(false);
  map<int, int> v;
  int i;
  int t;
  while (cin >> i) {
    v[i] = t++;
  }
  auto mi = i;
  auto mt = t;
  for (const auto p : v) {
    if (p.second < mt) {
      mi = p.first;
      mt = p.second;
    }
  }
  cout << mi << '\n';
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

上述程序大量使用未初始化的变量t,但GCC不报告-Wall或-Wuninitialized.为什么会这样?

值得注意的是,Clang抓住了它:

main.cpp:13:12: warning: variable 't' is uninitialized when used here [-Wuninitialized]
    v[i] …
Run Code Online (Sandbox Code Playgroud)

c++ gcc initialization clang

5
推荐指数
2
解决办法
695
查看次数

本地 Git 存储库线程安全吗?

如果两个用户同时尝试使用存储库,是否可以保证本地 Git 存储库没有竞争条件?

假设 Linux 系统上的两个用户git commit同时运行,或者一个用户正在应用补丁而另一个用户正在尝试检出分支,在这种情况下 Git 的行为是否明确定义?

git race-condition

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

缓冲缓存更改会阻止Meltdown吗?

如果新的CPU有一个缓存缓冲区,如果提交的指令只提交给实际的CPU缓存,那么类似于Meltdown的攻击仍然可能吗?

建议是让推测性执行能够从内存加载,但在实际提交之前不要写入CPU缓存.

cpu x86 caching cpu-architecture cpu-cache

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

为什么 numeric_limits&lt;atomic&lt;X&gt;&gt; 不会编译失败?

我刚刚通过针对以下表达式测试一个值来创建一个错误:

std::numeric_limits<decltype(allocationCount)>::max()
Run Code Online (Sandbox Code Playgroud)

在这种情况下,allocationCount是一个std::atomic<std::size_t>.

显然,上述表达式在 Clang 10 和 GCC 10 上编译并计算为 0

#include <atomic>
#include <cstdint>
#include <limits>
#include <string>

static std::atomic<std::size_t> allocationCount = 0;

uint64_t buggyGetMax() {
    return std::numeric_limits<decltype(allocationCount)>::max();
}

uint64_t correctGetMax() {
    return std::numeric_limits<decltype(allocationCount)::value_type>::max();
}
Run Code Online (Sandbox Code Playgroud)

我想使用的是

std::numeric_limits<decltype(allocationCount)::value_type>::max()
Run Code Online (Sandbox Code Playgroud)

产生我想要的值,即std::numeric_limits<std::size_t>::max().


我的问题是为什么std::numeric_limits<decltype(allocationCount)>还要编译?它不应该失败std::numeric_limits<std::string>吗?

如果这是设计使然,为什么是max()0?

c++ atomic decltype

3
推荐指数
1
解决办法
101
查看次数