为什么编译器似乎对没有做任何事情并且不消除它们的循环有礼貌?
C标准是否需要循环需要一些时间?
例如,以下代码:
void foo(void) {
while(1) {
for(int k = 0; k < 1000000000; ++k);
printf("Foo\n");
}
}
Run Code Online (Sandbox Code Playgroud)
运行速度比这个慢:
void foo(void) {
while(1) {
for(int k = 0; k < 1000; ++k);
printf("Foo\n");
}
}
Run Code Online (Sandbox Code Playgroud)
即使有-O3优化水平.我希望删除允许的空循环,从而在两个代码上获得相同的速度.
"花费的时间"是否应该由编译器保留的副作用?
我想知道是否有一个可以与GCC一起使用的选项,以获得有关编译器实际选择和执行的优化的详细报告.使用-opt-report的英特尔C编译器可以实现这一点.我不想查看汇编文件并找出优化.我特意寻找编译器选择的循环展开和循环平铺因子.
我已经通过网络问了几个关于这个问题的问题,但我没有找到任何问题的答案,或者它是针对另一种语言的,或者它没有完全回答(死代码不是无用的代码)所以这是我的问题:
编译器是否忽略(显式或非显式)无用代码?
例如,在此代码中:
double[] TestRunTime = SomeFunctionThatReturnDoubles;
// A bit of code skipped
int i = 0;
for (int j = 0; j < TestRunTime.Length; j++)
{
}
double prevSpec_OilCons = 0;
Run Code Online (Sandbox Code Playgroud)
for循环会被删除吗?
背景是我维护了很多代码(我没有写),我想知道无用的代码是否应该是目标,或者我是否可以让编译器处理它.
我有一段这样的代码:
if (state != "Ok")
{
Debug.WriteLine($"Error occured: {state}, {moreInfo}");
}
Run Code Online (Sandbox Code Playgroud)
如果我发布版本,编译器是否会优化它?或者评估是否仍然存在,从而花费一些处理时间?
我玩过Godbolt的CompilerExplorer.我想看看某些优化是多么好.我的最低工作范例是:
#include <vector>
int foo() {
std::vector<int> v {1, 2, 3, 4, 5};
return v[4];
}
Run Code Online (Sandbox Code Playgroud)
生成的汇编程序(通过clang 5.0.0,-O2 -std = c ++ 14):
foo(): # @foo()
push rax
mov edi, 20
call operator new(unsigned long)
mov rdi, rax
call operator delete(void*)
mov eax, 5
pop rcx
ret
Run Code Online (Sandbox Code Playgroud)
可以看出,clang知道答案,但在返回之前会做很多事情.在我看来,即使是矢量也是由于"operator new/delete"而创建的.
任何人都可以向我解释这里发生了什么以及它为什么不回归?
GCC生成的代码(此处未复制)似乎明确构造了向量.有谁知道海湾合作委员会无法推断出结果?
使用Java指令重新排序时,JVM会在编译时或运行时更改代码的执行顺序,这可能导致无关的语句无序执行.
所以我的问题是:
有人可以提供示例Java程序/片段,它可靠地显示指令重新排序问题,这也不是由其他同步问题(例如缓存/可见性或非原子r/w)引起的,就像我在这样的演示中尝试失败一样在我之前的问题中)
为了强调,我不是在寻找理论重新排序问题的例子.我正在寻找的是通过查看正在运行的程序的错误或意外结果来实际演示它们的方法.
除了一个错误的行为示例,只显示在一个简单程序的程序集中发生的实际重新排序也可能是好的.
java multithreading compiler-optimization instruction-reordering
我遇到了这样一种情况:对不必要的调用realloc进行优化会很有用.然而,似乎既没有铿锵也没有gcc做这样的事情(Godbolt).- 虽然我看到通过多次调用进行优化malloc.
这个例子:
void *myfunc() {
void *data;
data = malloc(100);
data = realloc(data, 200);
return data;
}
Run Code Online (Sandbox Code Playgroud)
我希望它能够优化到以下内容:
void *myfunc() {
return malloc(200);
}
Run Code Online (Sandbox Code Playgroud)
为什么clang和gcc都没有优化它? - 他们不允许这样做吗?
我们观察到一个奇怪的情况,VS2015 Update3编译器会在没有明显原因的情况下省略部分代码.
我们发现了
我们设法将这个代码段的罪魁祸首最小化:
#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
int _tmain(int, _TCHAR*[])
{
volatile int someVar = 1;
const int indexOffset = someVar ? 0 : 1; // Loop omitted
// const int indexOffset = !someVar; // Loop omitted
// const int indexOffset = 0; // Good
// const int indexOffset = 1; // Good
// const int indexOffset = someVar; // Good
// const int indexOffset = someVar + 1; // …Run Code Online (Sandbox Code Playgroud) c++ compiler-errors compiler-optimization visual-studio-2015
我有一个非常奇怪的编译器行为,其中G ++将计算拉入热循环,严重降低了生成的代码的性能.这里发生了什么?
考虑这个功能:
#include <cstdint>
constexpr bool noLambda = true;
void funnyEval(const uint8_t* columnData, uint64_t dataOffset, uint64_t dictOffset, int32_t iter, int32_t limit, int32_t* writer,const int32_t* dictPtr2){
// Computation X1
const int32_t* dictPtr = reinterpret_cast<const int32_t*>(columnData + dictOffset);
// Computation X2
const uint16_t* data = (const uint16_t*)(columnData + dataOffset);
// 1. The less broken solution without lambda
if (noLambda) {
for (;iter != limit;++iter){
int32_t t=dictPtr[data[iter]];
*writer = t;
writer++;
}
}
// 2. The totally broken solution with lambda
else …Run Code Online (Sandbox Code Playgroud) 在编译时gcc -O3,为什么以下循环没有矢量化(自动):
#define SIZE (65536)
int a[SIZE], b[SIZE], c[SIZE];
int foo () {
int i, j;
for (i=0; i<SIZE; i++){
for (j=i; j<SIZE; j++) {
a[i] = b[i] > c[j] ? b[i] : c[j];
}
}
return a[0];
}
Run Code Online (Sandbox Code Playgroud)
什么时候呢?
#define SIZE (65536)
int a[SIZE], b[SIZE], c[SIZE];
int foov () {
int i, j;
for (i=0; i<SIZE; i++){
for (j=i; j<SIZE; j++) {
a[i] += b[i] > c[j] ? b[i] : c[j];
}
}
return a[0];
}
Run Code Online (Sandbox Code Playgroud)
唯一的区别在于内部循环中的表达式的结果是 …