操作数

LLVM学习笔记(51)

烂漫一生 提交于 2019-12-23 08:53:23
3.10. X86折叠表的生成( v7.0) 指令折叠是在寄存器分配过程中执行的优化,目的是删除不必要的拷贝指令。例如,这样的一组指令: %EBX = LOAD %mem_address %EAX = COPY %EBX 可以被安全地替换为单条指令: %EAX = LOAD %mem_address 通常,后者较前者更小,更快。 在 X86 中,许多指令有内存形式与寄存器形式,即通过内存或寄存器传递操作数。为了执行指令折叠优化,需要某种方式将这两种形式的同一条指令关联起来。目前 LLVM 维护了几张体量庞大的表用于关联这些指令。 Intel 以色列的雇员 Ayman Musa 开发了这部分的 codegen ,希望能通过 TableGen 自动生成这些表。不过这部分代码目前因为尚有 bug ,没有默认生成。 这里 有关于这个 bug 的描述。 总的来说,这是因为 Musa 的主要假设是同一条指令的这两个形式共享相同的编码信息,除了负责“如何向指令传递参数”的部分,其中一个版本定义其中一个参数是寄存器,另一个版本定义它为内存操作数,而其他参数以相同方式传递。 但实际上,某些指令在寄存器与内存形式间有不同与上面假设的情形,例如 bt (比特测试)指令,其寄存器形式寄存器参数相关比特是第 4 、 5 、 6 比特(依赖于模式与寄存器大小),而内存形式相关比特是第 16 、 32 或 64

不吹不黑,关于 Java 类加载器的这一点,市面上没有任何一本图书讲到

流过昼夜 提交于 2019-12-23 07:31:06
一篇大神的译文,勉强(嗯。。相当勉强)地放在类加载器系列吧,第8弹: 实战分析Tomcat的类加载器结构(使用Eclipse MAT验证) 还是Tomcat,关于类加载器的趣味实验 了不得,我可能发现了Jar 包冲突的秘密 重写类加载器,实现简单的热替换 @Java Web 程序员,我们一起给程序开个后门吧:让你在保留现场,服务不重启的情况下,执行我们的调试代码 @Java web程序员,在保留现场,服务不重启的情况下,执行我们的调试代码(JSP 方式) 不吹不黑,关于 Java 类加载器的这一点,市面上没有任何一本图书讲到 一、前言 手里是锤子,看哪里都是钉子。最近学习类加载器的感觉就是如此,总是在想,利用它可以做到什么? 可以做到类隔离、不停服务执行动态调试代码,但是,还能做什么呢? 毕竟,Tomcat 出到现在了,也不支持更新某一个class 而不重启应用(这里重启应用的意思是,不是重启 Tomcat,而是重新部署 webapp),而热部署同样也是一个耗时的操作。有经验的同学应该知道Jrebel,开发环境的神器,有了它,平时用开发机和前端同学联调,再也不用频繁重启应用了。Jrebel可以做到动态更新某个class,并且可以马上生效,但是它的实现原理是迂回了一圈去解决这个问题的,且会有性能上的损耗,所以在生产环境也是不建议的(jrebel原理参考:

Java运算符

南笙酒味 提交于 2019-12-22 15:20:32
算术运算符注意项 如果两个操作数有一个为Long, 则结果为Long。 没有long时,结果为int。即使操作数全为short,byte,结果也是int。 如果两个操作数有一个为double,则结果为double。 只有两个操作数都是float,则结果才为float。 逻辑运算符 & 与、| 或、! 非(ture则返回false,false则返回ture)、^ 异或(不同为true,相同为false) boolean a = true ; boolean b = false; System.out.println(!b); //true System.out.println(a^b);//true 逻辑运算符的优先级 ! > & > | > ^ > && > || 位运算符 “>>” 、"<<"、"~"(取反)、"&"(位的与)、"|"(位的或)、"^"(位的异或) int b = 3<<2; //相当于:3 * 2 * 2; int d = 12>>2; //相当于:12/2/2; 注意 &和|既是逻辑运算符,也是位运算符。如果两侧操作数都是boolean类型,就作为逻辑运算符。如果两侧的操作数是整数类型,就是位运算符。 条件运算符 a ? b : c a为boolean类型的表达式,若为true则结果为b,若为false结果为c 来源: CSDN 作者: Sagittarius

8086寻址方式

こ雲淡風輕ζ 提交于 2019-12-22 00:00:32
CPU寄存器 8086 CPU 中寄存器总共为 14 个,且均为 16 位 。 即 AX,BX,CX,DX,SP,BP,SI,DI,IP,FLAG,CS,DS,SS,ES 共 14 个。 而这 14 个寄存器按照一定方式又分为了通用寄存器,控制寄存器和段寄存器。 通用寄存器: AX,BX,CX,DX 称作为数据寄存器: AX (Accumulator):累加寄存器,也称之为累加器; BX (Base):基地址寄存器; CX (Count):计数器寄存器; DX (Data):数据寄存器; 可以分为两个独立的 8 位的 AH(BH, CH, DH) 和 AL(BL, CL, DL) 寄存器 SP 和 BP 又称作为指针寄存器: SP (Stack Pointer):堆栈指针寄存器; BP (Base Pointer):基指针寄存器; SI 和 DI 又称作为变址寄存器: SI (Source Index):源变址寄存器; DI (Destination Index):目的变址寄存器; 控制寄存器: IP (Instruction Pointer):指令指针寄存器; FLAG:标志寄存器; 段寄存器: CS (Code Segment):代码段寄存器; DS (Data Segment):数据段寄存器; SS (Stack Segment):堆栈段寄存器; ES (Extra

JS中鲜为人知的问题: [] == ![]结果为true,而 {} == !{}却为false

馋奶兔 提交于 2019-12-21 01:03:00
console.log( [] == ![] ) // true console.log( {} == !{} ) // false 在比较字符串、数值和布尔值的相等性时,问题还比较简单。但在涉及到对象的比较时,问题就变得复杂了。最早的ECMAScript中的相等和不相等操作符会在执行比较之前,先将对象转换成相似的类型。后来,有人提出了这种转换到底是否合理的质疑。最后,ECMAScript的解决方案就是提供两组操作符: 相等和不相等——先转换再比较 (==) 全等和不全等——仅比较而不转换 (===) ECMAScript中相等操作符由两个等于号(==)表示,如果两个操作数相等,则返回true,这种操作符都会先转换操作数(通常称为强制转型),然后再比较它们的相等性 在转换不同的数据类型时,对于相等和不相等操作符:在JS高程中一书中给出如下的基本转换规则 ①、如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false转换为0,而true转换为1; ②、如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值 ③、如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则进行比较 这两个操作符在进行比较时则要遵循下列规则。 ①、null 和undefined 是相等的 ②、要比较相等性之前

数字SOC设计之低功耗设计入门(四)——RTL级低功耗设计

安稳与你 提交于 2019-12-20 17:37:07
二、RTL级低功耗设计     前面介绍了系统级的低功耗设计,换句话说就是在系统级降低功耗可以考虑的方面。系统级的低功耗设计,主要是由系统级设计、具有丰富经验的人员实现,虽然还轮不到我们设计,我们了解一下还是比较好的。我们前端设计人员的重点不在系统级设计上面,而是在RTL级(及综合)上面。下面我们就来介绍RTL编码与逻辑综合的低功耗设计,重点是 门控时钟 和 操作数隔离 技术。今天主要是讲解操作数和一些常见的方法;门控时钟由于内容比较多,所以写在后面。    (1)并行与流水的选择   对于某一个功能模块,我们可以通过并行的方式进行实现,也可以通过流水线的方式进行实现,这两种方法都是面积换速度,不过在一定的场合下可以降低功耗,需要灵活应用,下面就简要地介绍一下这两种方法(的使用)。    · 并行处理常用于数字信号处理部分。采用并行处理,可以降低系统工作频率,从而可能降低功耗。例如下图中:                  用两个乘法器来取代原设计中的一个乘法器。这样,时钟频率可以降低,系统的整体功耗会降低。采用这种方法,要在增加的面积与节省的功耗之间进行权衡。    · 流水线技术可以将一个较长的组合路径分成 M级 流水线。路径长度缩短为原始路径长度的 1 /M 。这样,一个时钟周期内 充/放电电容变为C/M 。如果在加入流水线之后,时钟速度不变,则在一个周期内,只需要对C

JavaScript中的数据类型转换

风格不统一 提交于 2019-12-20 09:26:47
本文中提到的“原始值”指的是undefined,null,Boolean,string和number。 本文中的对象是native对象,宿主对象(浏览器定义的对象)按照各自的算法转换。 JavaScript中共有六种数据类型,Undefined、Null、Boolean、Number、String和Object。 关于类型转换,JavaScript很有趣的一点是,它会根据 他期待的 数据类型自动进行类型转换。也就是说,即便你不给他他想要的,他也会 自己动手 把你给的变成他想要的。 那么这里就有两个问题, 他期待什么 和他 怎么变 。 我们先来看, 他怎么变? 我们知道,JavaScript中有用于类型转换的函数,比如String( ),Number( ),Boolean( ),Object( )。通过这些方法,我们可以 显式 的将数据转换为想要的类型。 下图是《JavaScript权威指南》中给各种数据类型相互转换的结果: 原始值的转换都很简单,和我们想象的几乎一致,其中复杂的是对象到原始值的转换,所以要单独进行讨论。 3.8.3中介绍了对象转换为不同类型的过程,不管要转换成什么类型,都是通过调用JavaScript会使用对象的两个转换方法——valueOf( )和toString( )来获得原始值,获取结果如下表: 只不过转换为不同类型获取原始值规则不同。

java并发编程笔记

回眸只為那壹抹淺笑 提交于 2019-12-19 12:41:52
java并发编程使用的是java.util.concurrent包下的类,主要是【原子包+锁包+处理并发的数据结构类】 原子类 锁类 Lock标准的实现是 ReentrantLock 重入锁 如何理解ReentrantLock的可重入和互斥? synchronized的实现原理 Lock的实现原理(即AQS(抽象队列同步器)算法) java的内置锁synchronized与类锁Lock的区别 专用于并发的数据结构类 Executor Executor本意是执行器,这里理解成线程池 用于此包中定义的Executor、ExecutorService、ScheduledExecutorService、ThreadFactory和可调用类的工厂和实用程序方法。此类支持以下类型的方法: 创建并返回一个ExecutorService,用来提供有用的配置环境 线程池 cpu工作原理【cpu一次只能做一件事】 冯诺依曼体系结构是现代计算机的基础。在该体系结构下,程序和数据统一存储,指令和数据需要从同一存储空间存取,经由同一总线传输,无法重叠执行。根据冯诺依曼体系,CPU的工作分为以下 5 个阶段:取指令阶段、指令译码阶段、执行指令阶段、访存取数和结果写回。 [1] 取指令(IF,instruction fetch),即将一条指令从主存储器中取到指令寄存器的过程。程序计数器中的数值

数据结构:c++算术表达式求值

我怕爱的太早我们不能终老 提交于 2019-12-19 08:46:24
算术表达式求值 [问题描述]  一个算术表达式是由操作数(operand)、运算符(operator)和界限符(delimiter)组成的。假设操作数是正实数,运算符只含加减乘除等四种运算符,界限符有左右括号和表达式起始、结束符“#”,如:#(7+15)*(23-28/4)#。引入表达式起始、结束符是为了方便。编程利用“运算符优先法”求算术表达式的值。 解题思路 : 1.首先建立两个栈用来分别存储操作数(operand)以及运算符(operator),为了减少代码量就直接调用STL中的栈方法来对“入栈”“出栈”以及“访问栈顶元素”进行操作。 2.最重要的一点是“如何才能使表达试正确遵循运算法则”(先乘除后加减,先算括号内的再处理括号外的),这就涉及到运算符优先级的问题,即在 Precede()方法中用二维数组定义好运算符的优先关系,然后根据方法返回的结果进行不同的操作。 3.最后是关于输入问题,操作数和运算符都只用字符型来输入,然后通过字符的ASCII码值来区分是是操作数还是运算符,然后正确进栈。 下面直接上代码,代码中有详细解释 # include <iostream> # include <stack> # include <cmath> using namespace std ; stack < char > OPTR ; stack < double > OPND ;

JVM内存模型——虚拟机栈

倾然丶 夕夏残阳落幕 提交于 2019-12-18 03:40:28
描述的是Java方法执行的内存模型,用于存储局部变量表(主要保存函数的参数以及局部的变量信息)、操作数栈、动态链接(反射机制就是一种实现)、方法出口等。随线程的启动而产生,线程的结束而消亡。局部变量分为两种情况,对于基本类型,会直接在栈上分配;如果是引用类型,对象会在堆中分配,相应的引用会在栈上(并不是绝对的,逃逸分析正是针对引用类型,如果小对象逃逸的情况不成立,会发生栈上分配)。 栈帧是java虚拟机栈的单位元素,每个线程每次调用方法,都会创建一个栈帧,方法调用结束则销毁栈帧。每个栈帧中都包含局部变量表、操作数栈、动态链接、方法出口。 局部变量表,用于存放方法参数和方法内部定义的局部变量。 操作数栈,方法的执行在操作数栈中完成,每个字节码指令往操作数栈进行写入和提取的过程,就是入栈和出栈的过程。 会出现的两种异常: StackOverflowError:单个线程请求的栈深度大于虚拟机栈允许的深度(方法递归太深); OutOfMemoryError:整个虚拟机栈内存耗尽无法申请到内存时(启动的线程太多)。 参考: https://www.cnblogs.com/manayi/p/9293302.html 来源: CSDN 作者: saishangmingzhu 链接: https://blog.csdn.net/saishangmingzhu/article/details