计算机指令

出栈序列研究

谁说我不能喝 提交于 2020-01-29 07:51:12
作者: John Waken 邮箱: JohnWaken@163.com 转载请著明: http://www.cnblogs.com/john-d/archive/2009/12/29/1635161.html 在学习数据结构的时候,老师出了这么个题目:1,2,3,4,5,6,7这七个数按顺序入栈,出栈序列有几种?当时我是先画了几个,比如1,2,3,4,5,6,7肯定可以,还有7,6,5,4,3,2,1也行,但是3,1,2,4,5,6,7就不合法。先考虑简 单的特殊情况是一种很好的思考方法,《concrete mathematics》就说过" smart mathematicians are not ashamed to think small ”,当然啦,我只是一个little programmer,不过每个人都应该提醒自己 think small。 还有另一个非常重要的思考方法——递归,特别是在计算机算法领域,我认为它是最重要的。递归首先要求把问题一般化,此题应该泛化为这样:1,2,3,... ,n这n个数依次入栈,出栈序列有几种? 递归的关键在于构造第推关系式,所以我们要定义一个描述结论的式子,在这里用 表示n个数依次入栈时出栈序列的个数。构造第推式就悲剧了,当时我推出它是一个类似于Catalan第推式的式子,那个兴奋哟!但是现在怎么也想不起来了。哎,人生最痛苦的事莫过于此

Java内存模型与线程

假如想象 提交于 2020-01-29 07:32:02
Java内存模型与线程 每秒事务处理数(Transactions Per Second,TPS)、 Java语言和虚拟机提供了许多工具,把并发编程的门槛降低了不少。另外,各种中间件服务器、各类框架 12.2 硬件的效率与一致性 现代计算机系统都不得不加入一层读写速度尽可能接近处理器运算速度的高速缓存(Cache)来作为内存与处理器之间的缓冲: 为了解决一致性的问题,需要各个处理器访问缓存时都遵循一些协议,在读写时要根据协议来进行操作,这类协议有MSI、MESI(IllinoisProtocol)、MOSI、Synapse、Firefly及Dragon Protocol,等等 为了使得处理器内部的运算单元能尽量被充分利用,处理器可能会对输入代码进行乱序执行(Out-Of-Order Execution)优化,处理器会在计算之后将乱序执行的结果重组,保证该结果与顺序执行的结果是一致的,类似,Java虚拟机的即时编译器中也有类似的指令重排序(Instruction Reorder)优化。 12.3 Java内存模型 用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果。 12.3.1 主内存与工作内存 此处的变量包括了实例字段、静态字段和构成数组对象的元素,但是不包括局部变量与方法参数,因为后者是线程私有的[插图],不会被共享

第二~五章小结 (2017-08-28 00:48:04)

微笑、不失礼 提交于 2020-01-29 02:53:21
第二章 x86处理器架构 中央处理单元(CPU)处理算术和逻辑运算。它包含了有限数量的存储位置,即寄存器,一个高频时钟用于同步其操作,一个控制单元和一个算术逻辑单元。内存存储单元在计算机程序运行时,保存指令和数据。总线是一组并行线路,在计算机不同部件之间传输数据。 一条机器指令的执行可以分为一系列独立的操作,称为指令执行周期。3个主要操作分别为取值、译码和执行。指令周期中的每一步都至少要花费一个系统时钟单位,即时钟周期。加载和执行过程描述了程序如何被操作系统定位,加载入内存,再由操作系统执行。 x86处理器系列有三种基本操作模式:保护模式、实地址模式和系统管理模式。此外,还有一个虚拟8086模式是保护模式的一个特例。Intel 64处理器系列有两种基本操作模式: 兼容模式和64位模式。在兼容模式下处理器可以运行16位和32位应用程序。 寄存器位CPU内的存储位置进行命名,其访问速度比常规内存要快很多。以下是对寄存器的简要说明: l 通用寄存器主要用于算术运算、数据传输和逻辑操作。 l 段寄存器存放预先分配的内存区域的基址,这些内存区域就是段。 l 指令指针寄存器存放的是下一条要执行指令的地址。 l 标志寄存器包含的独立二进制位于控制CPU的操作,并反映ALU操作的结果。 x86有一个浮点单元(FPU)专门用于高速浮点指令的执行。 微型计算机的心脏是它的主板,主板上有CPU

操作系统-进程管理

我怕爱的太早我们不能终老 提交于 2020-01-28 02:11:18
进程管理 要点: 基础:进程描述及控制 策略:进程调度 实现:互斥与同步 避免:死锁与饥饿 解决:几个经典问题 进程的引入 程序的顺序执行 源代码程序,目标程序和可执行程序 程序执行:编辑,编译,链接,执行 程序的结构:顺序,分支,循环结构 程序执行的特征:顺序性,封闭性,可再现性 程序并发执行 多道程序设计技术:多个程序并发执行 程序并发执行时的特征:间断性,非封闭性,不可再现性 并发执行引发的问题: 协调各程序的执行顺序:输入数据还未全部输入内存时,计算必须等待 多个执行程序共享系统资源,程序之间可能会相互影响,甚至影响输出结果 选择那些,多少个程序进入内存执行 内存中的执行程序谁先执行,谁后执行 内存如何有效分配? 进程的概念 定义:可并发执行的程序,在一个数据集合上的运行过程 申请、拥有资源~调度(线程) 程序:静态概念,是指令和数据的集合,可长期存储 进程与程序对应关系 一个程序可以对应一个进程或者多个进程 一个进程可以对应一个程序,或者一段程序 进程的特征 动态性 并发性 独立性 异步性 引入进程带来的问题 增加了空间开销:为进程建立数据结构 额外的时间开销:管理和协调,跟踪,填写和更新有关数据结构,切换进程,保护现场 更难控制:协调多个进程竞争和共享资源如何预防;解决多个集成因为竞争资源而出现的故障 处理机的竞争尤为突出 进程的结构 组成(进程映像):程序,数据集合

计算机系统大作业

半城伤御伤魂 提交于 2020-01-27 00:59:48
计算机系统 大作业 题 目 程序人生-Hello’s P2P 专 业 计算机类 学   号 1180300412 班   级 1803004 学 生 yiguanghui 指 导 教 师 计算机科学与技术学院 2019年12月 摘 要 关键词:计算机系统、编译链接、异常控制流、虚拟内存 摘要:本文较详细地跟踪介绍了hello.c在Linux下的生命周期,从被程序员创建,到在系统上运行,然后输出简单的消息,最后终止。本文通过计算机系统课程中相关的知识来分析hello.c在Linux开发工具下经历预处理、编译、汇编、链接、加载、执行、终止、回收等过程和结果,跟踪程序的链接、进程创建及加载、虚拟内存转换、高速缓存访问、异常控制流、I/O管理等过程。 目 录 第1章 概述… - 4 - 1.1 Hello简介… - 4 - 1.2 环境与工具… - 4 - 1.3 中间结果… - 4 - 1.4 本章小结… - 4 - 第2章 预处理… - 5 - 2.1 预处理的概念与作用… - 5 - 2.2在Ubuntu下预处理的命令… - 5 - 2.3 Hello的预处理结果解析… - 5 - 2.4 本章小结… - 5 - 第3章 编译… - 6 - 3.1 编译的概念与作用… - 6 - 3.2 在Ubuntu下编译的命令… - 6 - 3.3 Hello的编译结果解析… - 6 - 3.4

Java技术与Java虚拟机

时光怂恿深爱的人放手 提交于 2020-01-26 00:21:12
Java技术与Java虚拟机   说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成: Java编程语言 、 Java类文件格式 、 Java虚拟机 和 Java应用程序接口 (Java API)。它们的关系如下图所示: 图1 Java四个方面的关系   运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件)。最后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被 即时代码发生器 有选择的转换成机器码执行。从上图也可以看出Java平台由Java虚拟机和Java应用程序接口搭建,Java语言则是进入这个平台的通道,用Java语言编写并编译的程序可以运行在这个平台上。这个平台的结构如下图所示: 图2 Java平台结构图   在Java平台的结构中, 可以看出,Java虚拟机(JVM) 处在核心的位置,是程序与 底层操作系统 和 硬件 无关的关键。它的下方是 移植接口 ,移植接口由两部分组成: 适配器 和 Java操作系统 , 其中依赖于平台的部分称为适配器;JVM 通过移植接口在具体的平台和操作系统上实现;在JVM 的上方是Java的基本类库和扩展类库以及它们的API, 利用Java API编写的应用程序(application) 和小程序(Java

Java中的volatile

别说谁变了你拦得住时间么 提交于 2020-01-25 00:39:38
目录 可见性保证 Happens-before 保证 volatile 并不能满足所有场景 什么时候单单使用 volatile 就够了? volatile 的性能考虑 Java的关键字 volatile 用于将变量标记为“存储于主内存中”。更确切地说,对 volatile 变量的每次读操作都会直接从计算机的主存中读取,而不是从 cpu 缓存中读取;同样,每次对 volatile 变量的写操作都会直接写入到主存中,而不仅仅写入到 cpu 缓存里。 实际上,从 Java 5 开始关键字 volatile 除了能确保 volatile 变量直接从主存中进行读写,还有以下几个作用。 可见性保证 关键字 volatile 能确保数据变化在线程之间的可见性。 在多线程的应用中多个线程对 non-volatile 变量进行操作,线程在对它们进行操作的时候为了提高性能会将变量从主存复制到 cpu 缓存中。如果你的电脑包含的 cpu 不止一个, 那么每个线程可能会运行于不同的 cpu 上。这意味着,不同线程会将变量复制到不同 cpu 的缓存里。如下图: no-volatile 变量不能保证 Java 虚拟机(JVM)何时从主存中将数据读入cpu 缓存,也不能保证何时将数据从 cpu 缓存写入到主存中。这会带来一些问题,我将在下面解释。 想象一个场景,两个或两个以上线程可访问同一个共享对象

计算机系统之一计算机系统漫游

ぐ巨炮叔叔 提交于 2020-01-24 14:47:40
作为一个程序员,如果深入了解这些组件是如何工作的,以及这些组件是如何影响程序的正确性和性能的,以此来提高自己的技能,可以推荐<深入理解计算机系统>这本书,本系列也是作者在参读了这本书后的一些个人理解和对概念的认识,也可以当做我的个人笔记,希望对你有所帮助 代码无国界 计算机系统是由硬件和软件组成的 ,他们共同工作来运行应用程序.虽然系统的具体实现方式随着时间的变化而变化,但是系统内在的概念却没有改变.所有的计算机系统否有类似的硬件和软件组件,而且都执行这相似的功能. 1 #include <stdio.h> 2 int main () { 3 printf("hello world"); 4 } 这是一段c语言的源程序(源文件),在这里命名为hello.c 源程序实际上就是由值0和1组成的位(bit)序列,8个位被组织成一组,成为字节. 而每个字节表示程序中某个文本字符 大部分的现代系统都使用 ASCII 标准来表示文本字符,这中方式实际上就是用一个唯一的单字节大小的整数值来表示每个字符, 作为一个Java程序员每天接触最多的就是UTF-8 ,一开始也会迷糊,为了更好的理解他们之间的关系,推荐几篇博客: ASCII、Unicode、GBK和UTF-8字符编码的区别联系 ASCII,Unicode和UTF-8 hello.c程序以字节的方式存储在文件中.每个字节都有一个整数值

深入理解计算机系统(5.1)------优化程序性能

有些话、适合烂在心里 提交于 2020-01-24 04:56:09
  你能获得的对程序最大的加速比就是当你第一次让它工作起来的时候。   在讲解如何优化程序性能之前,我们首先要明确写程序最主要的目标就是使它在所有可能的情况下都能正常工作,一个运行的很快的程序但是却是错误的结果是没有任何用处的,所以我们在进行程序性能优化之前,首先要保证程序能正常运行,且结果是我们需要的。   而且在很多情况下,让程序跑的更快是我们必须要解决的问题。比如一个程序要实时处理视频帧或者网络包,那么一个运行的很慢的程序就不能解决此问题。再比如一个计算任务计算量非常大,需要数日或者数周,如果我们哪怕只是让它运行的快20%也会产生重大影响。 1、编写高效程序的切入点   ①、选择一组合适的算法和数据结构。   ②、编写出编译器能够有效优化以转换成高效可执行的源代码。   ③、多线程并行处理运算。   对于第一点,程序=数据结构+算法,选择合适的数据结构和算法无疑对于提高程序的运行效率有很大的影响。第二点对于编程者则需要理解编译器的优化能力以及局限性,编写程序看上去只是一点小小的改动,可能都会引起编译器优化方式很大的变化;第三点技术主要这对运算量特别大的运算,我们将一个大的任务分成多个小任务,这些任务又可以在多核和多处理器的某种组合上并行的计算,这里我们也需要知道,即使是利用并行性,每个并行的线程都要以最高性能的方式执行。 2、编译器的优化能力和局限性   正确性,正确性

编程小白之【C语言】- 第一个C程序代码分析!

╄→尐↘猪︶ㄣ 提交于 2020-01-23 01:57:26
一、代码分析 打开项目中的main.c文件(C程序的源文件拓展名为.c),可以发现它是第一个C程序中的唯一一个源文件,代码如下: 1.#include <stdio.h> ◐ #include 是C语言的预处理指令之一,所谓预处理,就是在编译之前做的处理,预处理指令一般以 # 开头 ◐ #include 指令后面会跟着一个文件名,预处理器发现 #include 指令后,就会根据文件名去查找文件,并把这个文件的内容包含到当前文件中。被包含文件中的文本将替换源文件中的 #include 指令,就像你把被包含文件中的全部内容拷贝到这个 #include 指令所在的位置一样 ◐ 如果被包含的文件拓展名为.h,我们称之为"头文件"(Header File),头文件可以用来声明函数("函数"就是面向对象中的"方法"),要想使用这些函数,就必须先用 #include 指令包含函数所在的头文件 ◐ #include 指令不仅仅限于.h头文件,可以包含任何编译器能识别的C/C++代码文件,包括.c,.hpp,.cpp等,甚至.txt,.abc等等都可以 ◐ 也就是说你完全可以将第3行到第9行的代码放到其他文件中,然后用 #include 指令包含进来,比如: 1> 将第3行到第9行的代码放到my.txt中 2> 在main.c源文件中包含my.txt文件 程序还是可以照常运行的,因为