考虑一下这种类型的代码,
while( !cond )
;
Run Code Online (Sandbox Code Playgroud)
如果cond未声明为volatile,则编译器可以通过将其缓存在寄存器中来优化它.在这种情况下,即使在设置cond后,while循环也将继续.
现在这是否意味着任何此类变量应始终声明为volatile?为什么编译器不够聪明才能意识到它不应该缓存这些变量?
如何在启用优化的情况下编译我的项目,并查看我的代码中更改了哪些优化.
例如:
我原来的代码:
printf("Test: %d",52);
for (int empty=0;i<100000;i++) {
//Nothing here
}
Run Code Online (Sandbox Code Playgroud)
现在,当我使用optimzations编译我的代码时,我想看到:(我认为它会像那样)
printf("Test: 52");
Run Code Online (Sandbox Code Playgroud) 我正在通过gcc学习优化.从优化级别可以看出,在级别Os中,gcc特别选择了减少可执行文件大小所需的优化.我写了简单的程序.
#include<stdio.h>
int main()
{
const int k=7;
printf("k = %d\n",k);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
并测试了所有级别.它给我的大小如下
O0 - 4883
O1 - 4883
O2 - 4867
O3 -4867
Os - 4879
Run Code Online (Sandbox Code Playgroud)
它应该给出Os级别的最小尺寸.但事实并非如此.任何人都可以告诉我,如果我错了.谢谢
var number = 3
Run Code Online (Sandbox Code Playgroud)
对比
var number: Int = 3
Run Code Online (Sandbox Code Playgroud)
使用特定类型与类型推断如何影响编译时间?有没有人做过这个主题的实验或一些数学运算?
这个运行时到底有没有影响?
我有以下程序:
public class TestClass
{
[Conditional("DEBUG")]
static void debug_foo()
{
Console.WriteLine("DEBUG foo");
}
static int Main(System.String[] args)
{
debug_foo();
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
我使用发布模式编译程序.我在程序集中找到了debug_foo方法的il代码.我无法理解这种解决方案的原因.我认为如果c#编译器可以理解,那个方法没有使用,那么编译器根本不需要生成il代码(例如,它不会在main函数中生成调用指令),因为它会减慢编译速度并增加汇编的大小.
constC++中函数参数的修饰符表示该函数不能改变参数值,但不保证在函数执行过程中不能被其他人改变。因此,编译器无法根据数据不变性进行任何优化。
据我了解,右值引用意味着给定的对象是临时的,因此其他人都无法访问其 data。在这种情况下,编译器可以进行积极的优化吗?
它将允许通过某种方式获得更快的代码
template<class T>
class Immutable
{
private:
const T val;
public:
operator const T && () { return std::move(val); }
};
Run Code Online (Sandbox Code Playgroud)
(只是示例代码),或者const&&当我们确定它们在函数调用期间无法更改时传递值。是否有可能,或者有一些未提及的问题?
c++ optimization constants compiler-optimization rvalue-reference
我一直在玩编译器优化和编译器资源管理器,并注意到 g++ 9.3(本地测试)中的以下缺点。该问题似乎在 g++ 10.1(在编译器资源管理器上测试)中仍然存在。我正在使用
请注意以下代码:
#include <iostream>
#include <iomanip>
constexpr auto fib( auto x )
{
if( x == 0 )
return 0;
else if( x == 1 )
return 1;
else
return fib( x - 1 ) + fib( x - 2 );
}
int main( int argc, char * argv[] )
{
std::cerr << std::setprecision(10) << fib( 47.l );
}
Run Code Online (Sandbox Code Playgroud)
编译器资源管理器链接在这里。
我知道如果我放了 47,模板参数推导会推导出 function int foo( int x ),但是即使我传递一个 long double 文字,这种情况仍然存在。
这会导致溢出。
为什么编译器不能在编译时推断出我的返回类型应该是双精度型?我会期望,因为 …
我们知道,根据 x86-64 约定,寄存器%rbx、%rbp和%r12–%r15被归类为被调用者保存的寄存器。While%r10和%r111是调用者保存的寄存器。但是当我在大多数情况下编译 C 代码时,例如函数P调用Q,我看到以下函数的汇编代码Q:
Q:
push %rbx
movq %rdx, %rbx
...
popq %rbx
ret
Run Code Online (Sandbox Code Playgroud)
我们知道,由于%rbx是一个被调用者保存的寄存器,我们必须将它存储在堆栈中,并在P以后为调用者恢复它。
但它不会更简洁并通过使用调用者保存的寄存器来保存堆栈操作%r10:
Q:
movq %rdx, %r10
...
ret
Run Code Online (Sandbox Code Playgroud)
所以被调用者不需要担心保存和恢复调用者的寄存器,因为调用者在调用被调用者之前已经把它推到了堆栈?
我可以使用 GCC 将汇编代码文件转换为可重新分配的文件。
gcc -c source.S -o object.o -O2
Run Code Online (Sandbox Code Playgroud)
优化选项是否有效?我可以期望 GCC 优化我的汇编代码吗?