缓冲器

多线程:硬件基础

懵懂的女人 提交于 2020-04-06 19:04:11
多线程:硬件基础 目录 多线程:硬件基础 一、高速缓存 二、缓存一致性协议 三、写缓冲器 一、高速缓存 现代CPU的处理性能是远远高于主内存,一次内存读或者写操作的时间内,CPU能够处理上百条指令。为了弥补CPU与内存之间性能的鸿沟,引入高速缓存(Cache)。 高速缓存的性能远远高于主内存,但是容量要小于主内存 。每个处理器都有其独立的高速缓存。有了高速缓存之后,处理器在做内存读写操作时就不必直接与主内存打交道,而是与缓存打交道(从缓存中读或写)。 缓存的数据结构相当于一个散列表,由若干桶和缓存条目组成,缓存条目又可以细分成三个部分:Data Block(缓存行)中存储了从内存中读取的或者将要写入内存的数据;Tag储存了缓存行中数据相应的内存地址的部分信息(内存地址的高位部分比特);Flag用于表示缓存行的状态信息,有哪些中状态值下面会进一步说明。 那么,处理器如果想操作储存在主内存地址A的变量时,具体时如何与缓存打交道的呢? 处理器把地址A解码为index,tag,offset三个数据。 首先通过index值定位到桶。 然后通过tag值比对定位到具体的缓存条目。 最后根据offset偏移量的值定位到缓存行中该变量的起始位置。 根据上述步骤如如果能够定位到相应的缓存行且所在缓存条目的Flag值表示缓存条目是有效的,我们就称相应的内存操作产生了 缓存命中 ,相反则称为 缓存未命中

蓝桥杯学习笔记(八)----------串口通信/NE555

邮差的信 提交于 2020-02-17 19:55:29
1.串口 通信原理 通信原理分为串行和并行,这次使用的是串行通信原理。 IAP15F2K61S2系列单片机具有2个采用UART(Universal Asychronous Receiver/Transmitter) 工作方式的全双工串行通信接口(串口1和串口2)。 每个串行口由2个数据缓冲器、一个移位寄存器、一个串行控制寄存器和一个波特率发生器等组成。 每个串行口的数据缓冲器由2个互相独立的接收、发送缓冲器构成,可以同时发送和接收数据。发送缓冲器只能写入而不能读出,接收缓冲器只能读出而不能写入,因而两个缓冲器可以共用一个地址码。99H(串口1:SBUF),9BH(串口2:S2BUF) 两个串行口都有4种工作方式,其中两种方式的波特率是可变的,另两种是固定的,以供不同应用场合选用。串行口1对应的硬件部分是TxD/P3.0和RxD/P3.1引脚。串行口2对应的硬件部分是TxD2,RxD2。 通过设置特殊功能寄存器AUXR1中的S1_ S1,串行口1(UART1)功能可以在[P30/P31],[P36RxD2/P37TxD2],[P16RxD3,P17TxD3]任意切*换。 寄存器 罗列一下需要的寄存器(用蓝色标注了) 串行控制寄存器SCON(可位寻址)和波特率选择特殊功能寄存器PCON(不可位寻址)。 实验1:单片机发送给上位机指定的字符串 void UartInit ( void )

第十一章多线程编程的硬件基础与Java内存模型

允我心安 提交于 2020-01-24 23:55:54
高速缓存内部结构示意图 缓存条目的结构 Data Block也被称为缓存行,它是高速缓存与主内存之间的数据交换最小单元,用于存储从主内存中读取或准备写往内存的数据。Tag则包含了与缓存行中数据相应的内存地址的部分信息(内存地址的高位部分比特)。Flag则用于表示响应缓存行的状态信息。 内存地址的解码结果包括tag、index以及offset三部分,index相当于桶号,tag相当于缓存条目的相对编号,offset是缓存行内的位置偏移。 MESI协议中一个缓存条目的Flag值有以下四种可能:Invalid(无效的,记为I)、shared(共享的,记为S),Exclusive(独占的,记为E)和Modified(更改过的,记为M)。 Processor 0读取数据S的实现 Processor 0写数据S的实现 写缓冲器 写缓冲器是处理器内部的一个容量比高速缓存还小的私有高速存储部件。一个处理器无法读取另外一个处理器的写缓冲器中的内容。 内存写操作的执行处理器在将写操作的相关数据写入写缓冲器之后便认为该写操作已经完成,一个处理器接收到其他处理器所回复的针对同一个缓存条目的所有Invalidate Acknowledge消息的时候,该处理器会将写缓冲器中针对相应地址的写操作的结果写入相应的缓冲行中。 无效化队列 引入无效化队列后

Golang之bytes.buffer

戏子无情 提交于 2019-12-05 01:06:08
bytes.buffer是一个缓冲byte类型的缓冲器存放着都是byte Buffer 是 bytes 包中的一个 type Buffer struct{…} A buffer is a variable-sized buffer of bytes with Read and Write methods. The zero value for Buffer is an empty buffer ready to use. (是一个变长的 buffer,具有 Read 和Write 方法。 Buffer 的 零值 是一个 空的 buffer,但是可以使用) Buffer 就像一个集装箱容器,可以存东西,取东西(存取数据) 创建 一个 Buffer (其实底层就是一个 []byte, 字节切片) 向其中写入数据 (Write mtheods) 从其中读取数据 (Write methods) 创建 Buffer缓冲器 var b bytes.Buffer //直接定义一个 Buffer 变量,而不用初始化 b.Writer([] byte ( "Hello " )) // 可以直接使用 b1 := new (bytes.Buffer) //直接使用 new 初始化,可以直接使用 // 其它两种定义方式 func NewBuffer(buf [] byte ) *Buffer func

ByteBuffer用法小结

只愿长相守 提交于 2019-12-05 01:05:14
在NIO中,数据的读写操作始终是与缓冲区相关联的.读取时信道(SocketChannel)将数据读入缓冲区,写入时首先要将发送的数据按顺序填入缓冲区.缓冲区是定长的,基本上它只是一个列表,它的所有元素都是基本数据类型.ByteBuffer是最常用的缓冲区,它提供了读写其他数据类型的方法,且信道的读写方法只接收ByteBuffer.因此ByteBuffer的用法是有必要牢固掌握的. 1.创建ByteBuffer 1.1 使用allocate()静态方法 ByteBuffer buffer=ByteBuffer.allocate(256); 以上方法将创建一个容量为256字节的ByteBuffer,如果发现创建的缓冲区容量太小,唯一的选择就是重新创建一个大小合适的缓冲区. 1.2 通过包装一个已有的数组来创建 如下,通过包装的方法创建的缓冲区保留了被包装数组内保存的数据. ByteBuffer buffer=ByteBuffer.wrap(byteArray); 如果要将一个字符串存入ByteBuffer,可以如下操作: String sendString="你好,服务器. "; ByteBuffer sendBuffer=ByteBuffer.wrap(sendString.getBytes("UTF-16")); 2.回绕缓冲区 buffer.flip();

Golang之bytes.buffer学习笔记

泄露秘密 提交于 2019-12-05 01:04:17
bytes.buffer是一个缓冲byte类型的缓冲器存放着都是byte Buffer 是 bytes 包中的一个 type Buffer struct{…} A buffer is a variable-sized buffer of bytes with Read and Write methods. The zero value for Buffer is an empty buffer ready to use. (是一个变长的 buffer,具有 Read 和Write 方法。 Buffer 的 零值 是一个 空的 buffer,但是可以使用) Buffer 就像一个集装箱容器,可以存东西,取东西(存取数据) 创建 一个 Buffer (其实底层就是一个 []byte, 字节切片) 向其中写入数据 (Write mtheods) 从其中读取数据 (Write methods) 创建 Buffer缓冲器 var b bytes.Buffer //直接定义一个 Buffer 变量,而不用初始化 b.Writer([]byte(“Hello “)) // 可以直接使用 b1 := new(bytes.Buffer) //直接使用 new 初始化,可以直接使用 // 其它两种定义方式 func NewBuffer(buf []byte) *Buffer func

SparkSQL自定义无类型聚合函数

匿名 (未验证) 提交于 2019-12-02 23:57:01
准备数据: Michael , 3000 Andy , 4500 Justin , 3500 Betral , 4000 一、定义自定义无类型聚合函数 想要自定义无类型聚合函数,那必须得继承org.spark.sql.expressions.UserDefinedAggregateFunction,然后重写父类得抽象变量和成员方法。 package com . cjs import org . apache . spark . sql . Row import org . apache . spark . sql . expressions .{ MutableAggregationBuffer , UserDefinedAggregateFunction } import org . apache . spark . sql . types . _ object UDFMyAverage extends UserDefinedAggregateFunction { //定义输入参数的数据类型 override def inputSchema : StructType = StructType ( StructField ( "inputColumn" , LongType ):: Nil ) //定义缓冲器的数据结构类型,缓冲器用于计算,这里定义了两个数据变量:sum和count

前端必须掌握的知识点

元气小坏坏 提交于 2019-12-01 10:08:18
1.webstorm是IDE(集成开发环境),不是编辑器 编辑器:首推:VIM(windows上用的叫做GVIM),Brakets 可选:atom,sublime,phpStorm webstorm>file>Power Save Mode如果被选择了,就会自动关闭webstorm的智能提示 2.查看本机的ip地址:cmd > ipconfig 3.一次完整的http通信过程: 建立Tcp连接 >>>>> web浏览器向web服务器发送请求 >>>>> web浏览器发送请求头信息 >>>> web服务器应答 >>>>> web服务器应答头信息>>>>> web服务器向浏览器发送数据 >>> web服务器关闭Tcp连接 4.CDN,CDS,DNS的区别: CDN:内容分发网络 (将缓存服务器分布到用户访问相对集中的地区或网络,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求) CDS:内容分发服务 (交易双发达成的,约定在未来一定期限内,信用保护买方按照约定的标准和方式向信用保护卖方支付信用保护费用, 由信用保护卖方就约定的一个或多个参考实体向信用保护买方提供信用风险保护的金融合约,属于一种合约类信用风险缓释工具) DNS:域名服务器 (进行域名和与之对应的ip地址转换的服务器) 5.SEO不是一个工具,而是一种思想

stm32学习笔记-USART

给你一囗甜甜゛ 提交于 2019-11-30 18:15:43
接口通过三个引脚与其他设备连接在一起(见图248)。任何USART双向通信至少需要两个脚:接收数据输入(RX)和发送数据输出(TX)。 RX:接收数据串行输。通过过采样技术来区别数据和噪音,从而恢复数据。 TX:发送数据输出。当发送器被禁止时,输出引脚恢复到它的I/O端口配置。当发送器被激活,并且不发送数据时,TX引脚处于高电平。在单线和智能卡模式里,此I/O口被同时用于数据的发送和接收。 ● 总线在发送或接收前应处于空闲状态 ● 一个起始位 ● 一个数据字(8或9位),最低有效位在前 ● 0.5,1.5,2个的停止位,由此表明数据帧的结束 ● 使用分数波特率发生器 —— 12位整数和4位小数的表示方法。 ● 一个状态寄存器(USART_SR) ● 数据寄存器(USART_DR) ● 一个波特率寄存器(USART_BRR),12位的整数和4位小数 ● 一个智能卡模式下的保护时间寄存器(USART_GTPR) 25.6517/754 关于以上寄存器中每个位的具体定义,请参考寄存器描述第节:USART寄存器描述。 发送配置步骤: 1. 通过在USART_CR1寄存器上置位UE位来激活USART 2. 编程USART_CR1的M位来定义字长。 3. 在USART_CR2中编程停止位的位数。 4. 如果采用多缓冲器通信,配置USART_CR3中的DMA使能位(DMAT)

Golang之缓冲器bytes.Buffer

岁酱吖の 提交于 2019-11-26 03:43:37
声明一个Buffer的四种方法: var b bytes.Buffer // 直接定义一个Buffer变量,不用初始化,可以直接使用 b := new(bytes.Buffer) //使用New返回Buffer变量 b := bytes.NewBuffer(s []byte) //从一个[]byte切片,构造一个Buffer b := bytes.NewBufferString(s string) //从一个string变量,构造一个Buffer 往Buffer中写入数据 b.Write(d []byte) //将切片d写入Buffer尾部 b.WriteString(s string) //将字符串s写入Buffer尾部 b.WriteByte(c byte) //将字符c写入Buffer尾部 b.WriteRune(r rune) //将一个rune类型的数据放到缓冲器的尾部 b.WriteTo( w io.Writer ) //将Buffer中的内容输出到实现了io.Writer接口的可写入对象中 注:将文件中的内容写入Buffer,则使用ReadForm(i io.Reader) 从Buffer中读取数据到指定容器 c := make([]byte,8) b.Read(c) //一次读取8个byte到c容器中,每次读取新的8个byte覆盖c中原来的内容 b.ReadByte