lecture17_Process_Level_Parallelism
Process-Level ParallelismMultiprocess Framework
不同的核不分享内存,但是共享一个文件系统
在多线程程序运行时,一个线程 crash,整个程序可能 crash;但是多核程序,每个核之间是独立的,如果一个核 crash,其他的核可以继续运行
不同的核交流占用大量时间
将一个大问题分解成独立的小问题;以此来减少数据的传输时间损耗
lecture18_Caches
Caches
Memory Hierarchy (层次化内存)
寄存器离 CPU 最近,使用也最快;但是很贵;每个 CPU 只有少量寄存器
DRAM 更适合存储大量数据,但是速度更慢
需要数据总线进行传输
加速方式
Hardware Multithreaing
在等待数据的过程中,切换到另一个进行去执行任务
每个物理核含有两个 PC 核寄存器组,所以上下文切换很快
Prefetching
每个周期预取指令和数据
Caching
利用空间局部性和时间局部性,减少和主存之间的数据传输
缓存中存放被主存使用的数据副本
主存中存放磁盘上的数据副本
层次化管理
Registers <—> Memory
通过编译器或者汇编级别编程
Cache <—> 主存
通过缓存控制硬件
Main Memory <—> Disks
通过操作系统(虚拟内存)
通过编程者 (files)
Cache 三种映射
全相联映射
每个数据可以被映射到 n 个位置
物理地址被分为 tag and offset
直接映射
每个数据只 ...
lecture21_Virtual_Memory
Virtual Memory直接使用物理内存问题
没有足够空间;RISC-V 只提供 32bit 空间即 4GB
地址空间有空洞
不能保证其他程序不访问同一块内存
Benefits
允许运行自身大小比主存大得多的程序;只有工作的页放在主存,其他页放在磁盘;由OS进行页的请求和置换
OS可以共享内存并实现程序的互相保护
隐藏机器级的不同
lecture2_Intro_to_C
Intro to CGreat idea in Computer Architecture1. Abstraction
(Layers of Representation/Interpretation)
2. Moore’s Law(摩尔定律)3. Principle of Locality/Memory Hierarchy(局部性和内存层次性原则)
4. Parallelism(并行)
加速频繁事件(Amdahl’s law)
5. Performance Measurement & Improvement6. Dependability via redundancy(冗余实现可靠性)
RAID…
失去一个数据中心,但是整个网络不会宕机
Compiled & Interpreted(编译和解释)
Translation happens in two ways○ Compilation○ Interpretation○ Some languages use both!
C compilers map C programs direct ...
lecture16_Thread_Level_Parallelism
Thread-Level Parallelism
SISD:线性执行指令,没有并行
RISC-V 单周期 CPU
SIMD:单指令流,多数据流
Intel instrinsics
GPUS
MISD:多指令流,单数据流
Deep learning acceleration chips
MIMD:多指令流,多数据流
Modern processors
多核执行模型
独立资源
Datapath (PC, registers, ALU)
Highest level caches (L1, L2 cache)
共享资源
Memory (DRAM)
3rd level cache
线程
一个进程可以可以分裂或者 fork 出新线程;这些线程可以同时运行
对于单核来说,CPU 分时运行线程
每个 CPU 核提供一个或多个硬件的线程来执行指令
硬件多线程
在处理器硬件中有两个 PC 核对应的寄存器组
simultaneous multithreading (SMT) or hyperthreading (HT)
Big/little Process ...
lecture4_C_Memory
C Memorymemory alignment(内存对齐)
Memory alignment: a system-dependent rule that tells us where datacan be stored (usually not at every byte)
Can be accomplished with the “aligned” attribute__attribute__((aligned(n)));
Strings
Example: The string “Hi” is stored in memory as an array of characters. This array would look like: {‘H’, ‘i’, ‘\0’}
If the null terminator is missing, C will continue to read memory as ifit was part of the string until it comes across a byte that happens to have value 0. ...
xv6-BootLoader
BootLoader
查看对应的文件使用runoff.list文件
计算机启动时的硬件动作
PC 机上电时运行的第一条指令总是存储在 ROM 中的 BIOS 指令,BIOS 固件对硬件进行自检然后按照规范总是从磁盘的中的第一个扇区载入程序,并将其放入 0x07c00 地址处,一般情况下这个便是 BootLoader,有些 BootLoader 较大无法用一个扇区存放,所以一般会分为好几部分,由最初的部分将它们载入到内存,然后将控制权交给 BootLoader。
设置 A20 地址线 # Physical address line A20 is tied to zero so that the first PCs # with 2 MB would run software that assumed 1 MB. Undo that.seta20.1: inb $0x64,%al # Wait for not busy testb $0x2,%al jnz seta20.1 movb $0xd1,%al ...
xv6-中断和系统调用
Interrupt and System call
xv6 通过一个存放函数指针的数组来作为中断向量表,在 main 函数初始化过程中,调用tvinit 函数完成中断向量表的初始化。tvinit 将每一个中断处理程序的地址写入 idt 数组中,idtinit 将数组地址载入中断向量表寄存器,硬件能够根据中断向量表寄存器准确找出中断处理程序,xv6 使用 vector.pl 脚本生成 vector 数组,vector 数组存放着每个中断处理程序的入口地址,xv6 简单地将所有的中断处理程序指向 alltraps,由 alltraps 来负责具体的处理。在调用 alltraps 之前,xv6 统一压入 errnum 和 trapnum 来区分是 256 情况中的哪种。
voidtvinit(void){ int i; for(i = 0; i < 256; i++) SETGATE(idt[i], 0, SEG_KCODE<<3, vectors[i], 0); SETGATE(idt[T_SYSCALL], 1, SEG_KCODE<< ...
xv6-多核启动
内核初始化和多核启动
查看对应的文件使用runoff.list文件
内核初始化
bootloader 将内核载入物理地址 0x100000,通过跳转命令正式将控制权交给内核
# Entering xv6 on boot processor, with paging off..globl entryentry:
这里的 entry 便是内核最开始运行的代码,前面说过,此时虽然已经开始了保护模式但是分页机制并没有开启,这个时候线性地址等于物理地址,但是内核中所有的符号地址都是位于高内存处的虚拟地址,所以最开始先设置页表并开启分页机制
# Turn on page size extension for 4Mbyte pagesmovl %cr4, %eaxorl $(CR4_PSE), %eaxmovl %eax, %cr4# Set page directorymovl $(V2P_WO(entrypgdir)), %eaxmovl %eax, %cr3# Turn on paging.movl %cr0, %eaxorl $(CR0_PG ...
xv6-内存管理
内存管理物理内存初始化
xv6 在 main 函数中调用 kinit1 和 kinit2 来初始化物理内存,kinit1 初始化内核末尾到物理内存 4M 的物理内存空间为未使用
kinit2 初始化剩余内核空间到 PHYSTOP 为未使用
kinit1(end, P2V(4*1024*1024)); // phys page allocatorkinit2(P2V(4*1024*1024), P2V(PHYSTOP)); // must come after startothers()
kinit2 在内核构建了新页表后,能够完全访问内核的虚拟地址空间,所以在这里初始化所有物理内存,并开始了锁机制保护空闲内存链表。
voidkinit2(void *vstart, void *vend){ freerange(vstart, vend); kmem.use_lock = 1;}
内核新页表初始化
main 函数通过调用 kvmalloc 函数来实现内核新页表的初始化
pde_t *kpgdir; // for use in scheduler()void ...