我正在比较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++ 示例中,我定义了一个计算树最左边路径高度的函数。
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) #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) 如果两个用户同时尝试使用存储库,是否可以保证本地 Git 存储库没有竞争条件?
假设 Linux 系统上的两个用户git commit同时运行,或者一个用户正在应用补丁而另一个用户正在尝试检出分支,在这种情况下 Git 的行为是否明确定义?
如果新的CPU有一个缓存缓冲区,如果提交的指令只提交给实际的CPU缓存,那么类似于Meltdown的攻击仍然可能吗?
建议是让推测性执行能够从内存加载,但在实际提交之前不要写入CPU缓存.
我刚刚通过针对以下表达式测试一个值来创建一个错误:
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?