编译器优化

Delphi编译指令说明

▼魔方 西西 提交于 2020-03-12 23:51:42
Delphi快速高小的编译器主要来自Object PASCAL的严谨,使用Delphi随时都在与编译器交流,大部分情况下不需要干涉编译器的运行,但是有时也需要对编译器进行必要的设置。 ********************************************************************************************** A.1 使用编译设置对话框 编译器的编译指令是用于指定编译器对项目编译过程的动作和行为。可以通过[Project]->[Options]->[Complier]选项页进行设置,绝大部分的编译环境都可以通过这一对话框进行调整,他包含了对代码、语法、调试信息等的设置。 1.代码设置(Code Generation) Optimization: 代码优化开关 Aligned record fields: 字对齐数据。这个编译指令能够在变量和类型化常量的字节对齐和字对齐之间进行切换,其作用是全局的。 Stack frames: Windows 堆栈帧。其作用域是局部的,他使编译器成为远端过程和函数生成特定的开头和结尾代码。这个指令用于Windows 3.0的实模式,对所有Delphi应用程序他应该是关闭的。 Pentium-safe FDIV: Pentium安全FDIV检查

java volatile详解(转)

随声附和 提交于 2020-03-12 17:05:04
volatile的特性 当我们声明共享变量为volatile后,对这个变量的读/写将会很特别。理解volatile特性的一个好方法是:把对volatile变量的单个读/写,看成是使用同一个监视器锁对这些单个读/写操作做了同步。下面我们通过具体的示例来说明,请看下面的示例代码: class VolatileFeaturesExample { volatile long vl = 0L; //使用volatile声明64位的long型变量 public void set(long l) { vl = l; //单个volatile变量的写 } public void getAndIncrement () { vl++; //复合(多个)volatile变量的读/写 } public long get() { return vl; //单个volatile变量的读 } } 假设有多个线程分别调用上面程序的三个方法,这个程序在语意上和下面程序等价: class VolatileFeaturesExample { long vl = 0L; // 64位的long型普通变量 public synchronized void set(long l) { //对单个的普通 变量的写用同一个监视器同步 vl = l; } public void getAndIncrement () { /

《深度探索C++对象模型》第三章:Data 语意学

ぃ、小莉子 提交于 2020-03-12 11:22:57
sizeof 内存对齐的一些规则: #pragma pack(n) 预编译指令,可用来设置多少个字节对齐,n的缺省数值是按照编译器自身设置,一般为8,合法的数值分别是1、2、4、8、16,其它的无效。 offset从0开始,每个数据成员开始存放的offset值为min(n, 数据成员大小)的整数倍。 在数据成员完成各自的存放之后,整个类也将进行内存对齐,其大小为min(n, 整个类中最大成员的大小)的整数倍。 如果一个类是空类,即里面无任何数据成员,那么它会有一个隐藏的1 byte 大小,那是被编译器安插进去的一个char,这使得两个objects得以在内存中配置独一无二的地址。 sizeof的大小受到三个因素的影响: 语言本身所造成的额外负担(vptr、vbptr(有些编译器有,也有可能会共用vptr)) 编译器对于特殊情况所提供的优化处理(如空类) 内存对齐的限制 class X {}; class Y : public virtual X {}; class Z : public virtual X {}; class A : public Y, public Z {}; int main() { cout << sizeof(X) << endl; //1 cout << sizeof(Y) << endl; //4 cout << sizeof(A) << endl; /

MDK编译优化笔记

北战南征 提交于 2020-03-11 06:00:37
在一次使用MDk的编译优化等级比较高的时候发现编译不优化时功能正常,开了优化等级0 2就出现异常,调试中看了很多博客总结一下。 一个变量,如果你的主程序要用到,同时中断还要用到,要加volatile修饰。告诉编译器这个变量是可能随时发生变化的,使得编译器编译程序的时候,每次都从RAM里面读取数据,而不是使用之前缓存到寄存器里面的值。 对于多任务的程序,如果一个公共变量被多个任务用到也要加volatile修饰。 同时变量定义的时候用了关键字volatile修饰,但是在其他文件引用时不加volatile变量修饰一样会被编译器优化掉。现则反过来想想,原因还是很简单的,MDK编译多个文件时是分别编译,最后再用链接器链接,当编译的时候一个模块引用另外一个模块的变量,完全是靠的变量声明,如果声明都不加volatile,那么引用的模块肯定会把变量当成普通变量的,再反推一下,如果原变量没有加volatile,但是声明的时候加了volatile,是不是引用的模块会将这个变量当成volatile型变量呢   C编译器是以每个C文件作为基本编译单元的,称为模块,被编译为obj;而模块之间的函数或变量访问都是通过标号来实现的,标号本身没有任何属性,只是提供给链接器使用的一个符号名称而已,标号的属性完全就靠调用的地方的原型声明来决定的!因此,你在一个.C模块中定义为volatile,仅仅是在

C++面试题

时光怂恿深爱的人放手 提交于 2020-03-08 08:06:32
语言基础类 1. 指针和引用的区别? (1)指针有自己的一块空间,而引用只是一个别名;  (2)使用 sizeof 看一个指针的大小为 4 字节(32位,如果要是64位的话指针为8字节),而引用则是被引用对象的大小。 (3) 引用必须在定义时被初始化,指针不必; (4)不存在指向空值的引用,但存在指向空值的指针。 2.static和 const的用法,(能说出越多越好)(重点) 首先说说const的用法(绝对不能说是常数) 1.限定变量为不可修改。 2.限定成员函数不可以修改任何数据成员。 3.使用const关键字修饰的变量,一定要对变量进行初始化 下面的声明都是什么意思? const int a; a是一个常整型数 int const a; a是一个常整型数 const int *a; a是一个指向常整型数的指针,整型数是不可修改的,但指针可以 int * const a; a为指向整型数的常指针,指针指向的整型数可以修改,但指针是不可修改的 int const * a const; a是一个指向常整型数的常指针,指针指向的整型数是不可修改的,同时指针也是不可修改的 通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。 合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。

iar、keil(ac5+ac6)编译效果小记

六月ゝ 毕业季﹏ 提交于 2020-03-06 10:27:29
stm32F103et6平台,cubemx生成的两个IDE工程 1、均无开启任务优化 iar8.32如下: keil5.29 ac5编译器 : keil5.29 ac6编译器 : 同样的代码,不开优化的情况下,ac6反而代码空间比较大 2、开启最高优化: iar:high(size) keil5.29 ac5编译器 :level 3 keil5.29 ac5编译器 :-Oz 开启优化的情况,ac6的表现还是不错的。 来源: https://www.cnblogs.com/CodeWorkerLiMing/p/12424942.html

Rust 编译模型之殇

妖精的绣舞 提交于 2020-03-02 18:03:46
作者介绍: Brian Anderson 是 Rust 编程语言及其姊妹项目 Servo Web 浏览器的共同创始人之一。他目前在 PingCAP 担任高级数据库工程师。 感谢 Rust 中文社区翻译小组对本文翻译及审校上的贡献: 翻译:张汉东、黄珏珅 审校 :吴聪 Rust 编译缓慢的根由在于语言的设计。 我的意思并非是此乃 Rust 语言的 设计目标 。正如语言设计者们相互争论时经常说的那样,编程语言的设计总是充满了各种权衡。其中最主要的权衡就是: 运行时性能 和 编译时性能 。而 Rust 团队几乎总是选择运行时而非编译时。 因此,Rust 编译时间很慢。这有点让人恼火,因为 Rust 在其他方面的表现都非常好,唯独 Rust 编译时间却表现如此糟糕。 Rust 与 TiKV 的编译时冒险:第 1 集 在 PingCAP ,我们基于 Rust 开发了分布式存储系统 TiKV 。然而它的编译速度慢到足以让公司里的许多人不愿使用 Rust。我最近花了一些时间,与 TiKV 团队及其社区中的其他几人一起调研了 TiKV 编译时间缓慢的问题。 通过这一系列博文,我将会讨论在这个过程中的收获: 为什么 Rust 编译那么慢,或者说让人感觉那么慢; Rust 的发展如何造就了编译时间的缓慢; 编译时用例; 我们测量过的,以及想要测量但还没有或者不知道如何测量的项目;

C/C++中的变量与常量

删除回忆录丶 提交于 2020-02-28 06:15:11
C/C++中的变量 在定义变量时,C与C++ 有明显的区别。这两种语言都要求变量使用前必须定义,但是C(和许多其他传统过程语言)强制在作用域的开始处就定义所有的变量,以便在编译器创建一个块时,能够给所有的这些变量分配空间。(这个说法已经是老皇历了,现在的编译器即使是不在开始处定义变量也是可以做优化的,所以写C程序时完全可以像C++那样在任何方便的地方定义变量)。在C/C++中变量与函数在内存中是分开存放的。 全局变量 全局变量时在所有函数体的外部定义的,程序的所有部分(甚至其他文件中的代码)都可以使用。全局变量不受作用域的影响,总是可用的(即全局变量的生命期一直到程序的结束)。如果在一个文件中使用extern关键字来声明另一个文件中存在的全局变量,那么这个文件可以使用这个数据。全局变量会被分配在内存的堆上。 局部变量 局部变量出现在一个作用域内,是局限于一个函数的。局部变量经常被称为自动变量(automatic variable),因为是进入作用域时自动生成,离开作用域时候自动消失。关键字auto可以显示的说明这个问题,但是局部变量默认为auto,所以没有必要声明为auto。局部变量的内存中会被放在栈上。 寄存器变量:是一种局部变量。关键字register告诉编译器“尽可能快地访问这个变量”。加快访问速度取决于实现,但是,正如名字所暗示的那样子

C Primer Plus(第五版)1

筅森魡賤 提交于 2020-02-28 03:44:48
这是C Primer Plus(第五版)的第一章,上传上来主要是方便我进行做笔记,写注释,还有我会删掉一些“废话”等。 1.1 C语言的起源 贝尔实验室的 Dennis Ritchie 在1972年开发了C,当时他正在与Ken Thompson 一起设计 UNIX操作系统 。 1.4 计算机工作的基本原理 现代计算机可分为几个部件。中央处理单元(或称CPU)担负着绝大部分的计算工作,随机访问存储器(或称RAM)作为一个工作区来保存程序和文件;永久存储器,一般是硬盘,即使在计算机关机时也能记下程序和文件;还有各种外围设备(如键盘,鼠标和监视器)用来提供人与计算机之间的通信。CPU负责处理程序,所以我们集中来讨论它的功能。 CPU 的工作非常简单,至少在我们所做的这一简短的描述中是这样的。它从内存中获取一个指令并执行该指令,然后从内存中获取下一个指令并执行,。一个千兆 CPU 可以在一秒种内进行大约一亿次这样的操作,所以 CPU 能以惊人的速度来从事其枯燥的工作。CPU 有自己的小工作区,该工作区由若干个寄存器(registers)组成,每个寄存器可以保存一个数。一个寄存器保存下一条指令的内存地址,CPU 使用该信息获取下一条指令。获取一条指令后,CPU 在另一个寄存器中保存该指令并将第一个寄存器的值更新为下一条指令的地址。CPU 只能理解有限的指令(指令集)。还有

即时(JIT)编译器有什么作用?

ぃ、小莉子 提交于 2020-02-27 12:40:01
与非JIT编译器相比,JIT编译器专门做什么? 有人可以给出简洁明了的描述吗? #1楼 Java编译器生成字节代码(与体系结构无关)后,执行将由JVM(在Java中)处理。 字节码将由加载程序加载到JVM中,然后解释每个字节指令。 当我们需要多次调用一个方法时,我们需要多次解释相同的代码,这可能比需要花费更多的时间。 因此,我们有了JIT(即时)编译器。 将字节加载到JVM(运行时)后,整个代码将被编译而不是解释,从而节省了时间。 JIT编译器仅在运行时起作用,因此我们没有任何二进制输出。 #2楼 JIT-及时,单词本身说出何时需要(按需) 典型场景: 源代码已完全转换为机器代码 JIT场景: 源代码将转换为汇编语言,例如结构[对于C#来说,是用于ex IL(中间语言),对于Java,是ByteCode)。 仅当应用程序需要的中间代码仅转换为机器代码时,才将中间代码转换为机器语言。 JIT与非JIT比较: 在JIT中,并非所有代码都首先转换为机器代码,一部分必需的代码将被转换为机器代码,然后,如果所调用的方法或功能不在机器中,则将其转换为机器代码...它减少了CPU的负担。 由于机器代码将在运行时生成...。JIT编译器将生成针对机器的CPU体系结构进行了优化的机器代码。 JIT示例: 在Java中,JIT在JVM(Java虚拟机)中 在C#中,它在CLR(公共语言运行时)中