首页 > 其他 > 详细

实验总结分析报告:从系统的角度分析影响程序执行性能的因素

时间:2021-05-16 18:58:36      阅读:15      评论:0      收藏:0      [点我收藏+]

Linux系统概念模型

Linux操作系统有四大功能:进程管理、内存管理、文件系统驱动程序管理等。从下面这张图可以看出Linux操作系统概念模型。

技术分享图片

一、模型验证 

示例一: 分配内存

当应用进程(如c语言使用malloc)申请内存时,调用系统api,系统从用户态进入内核态,在Linux系统上,程序被载入内存时,内核为用户进程地址空间建立了代码段、数据段和堆栈段,在数据段与堆栈段之间的空闲区域用于动态内存分配。 内核数据结构mm_struct中的成员变量start_code和end_code是进程代码段的起始和终止地址,start_data和 end_data是进程数据段的起始和终止地址,start_stack是进程堆栈段起始地址,start_brk是进程动态内存分配起始地址(堆的起始 地址),还有一个 brk(堆的当前最后地址),就是动态内存分配当前的终止地址。 C语言的动态内存分配基本函数是malloc(),在Linux上的基本实现是通过内核的brk系统调用。brk()是一个非常简单的系统调用,只是简单地改变mm_struct结构的成员变量brk的值。 mmap系统调用实现了更有用的动态内存分配功能,可以将一个磁盘文件的全部或部分内容映射到用户空间中,进程读写文件的操作变成了读写内存的操作。在 linux/mm/mmap.c文件的do_mmap_pgoff()函数,是mmap系统调用实现的核心。do_mmap_pgoff()的代码,只是新建了一个vm_area_struct结构,并把file结构的参数赋值给其成员变量m_file,并没有把文件内容实际装入内存。。

进程分配内存有两种方式,分别由两个系统调用完成:brk和mmap(不考虑共享内存)。

1、brk是将数据段(.data)的最高地址指针_edata往高地址推;

2、mmap是在进程的虚拟地址空间中(堆和栈中间,称为文件映射区域的地方)找一块空闲的虚拟内存

这两种方式分配的都是虚拟内存,没有分配物理内存。在第一次访问已分配的虚拟地址空间的时候,发生缺页中断,操作系统负责分配物理内存,然后建立虚拟内存和物理内存之间的映射关系。当缺页中断发生时,Linux系统进行以下操作:

1、检查要访问的虚拟地址是否合法 
2、查找/分配一个物理页 
3、填充物理页内容(读取磁盘,或者直接置0,或者啥也不干) 
4、建立映射关系(虚拟地址到物理地址) 
5、重新执行发生缺页中断的那条指令 

 只要进程请求内存,内核只要满足要求就会给其分配页面。如果进程不再需要页面,内核就会将其回收。

alloc_page()//该函数用于请求单页

alloc_pages()//该函数用于请求4个页面

__get_free_page()/__get_dma_pages()  //返回32为虚拟地址,该地址是分配页面的首地址

__free_page()/__free_pages() //释放页面

每当页面被分配和回收的时候,系统都会遇到外部碎片或内存碎片的问题(即页面散布在内存中,即使可用页面足够多,但是无法分配大块的连续页面)。为了解决这个问题,Linux系统提供了伙伴算法。伙伴系统把内存中空闲块组成链表,将不同大小的空闲内存块组织起来(我猜测是将相同大小的组织在一起),虽然大小不一样,但是都是2的幂次方。当系统中有进程释放没存的时候,伙伴系统就会搜索与所释放块大小相等的可用空闲内存块,如果找到相邻的空闲块,就将其合并成两倍于自身大小的块。这种合并的块称为伙伴。

当内存分配完成,系统从内核态返回用户态。

示例二: 读文件

  1. 进程调用库函数read向内核发起读文件请求

  2. 触发系统调用sys_read(),获得当前进程的控制块

  3. 系统调用read()会触发相应的VFS的read()函数

  4. 然后找到file结构,再找到fd数组,以fd为索引找到对应项,然后找到系统打开文件表

  5. 执行系统打开文件表里面的file operation里面的read

二、影响应用程序性能表现的因素

1. 硬件方面

  • CPU: CPU主频的大小, CPU数量以及缓存数量
  • 内存: 物理内存越大性能越好, 但牺牲了空间, 加大了消耗
  • I/O
  • 网络

2. 软件方面

把应用程序带入模型分析性能

  • 首先,应用程序需要从磁盘拷贝到内存,需要进行逻辑地址 -> 线性地址 ->物理地址的转换,这里可以通过快表机制来提升性能
  • 由物理地址定位到磁盘地址, 需要进行I/O请求, 可以采用不同的磁盘调度策略来影响性能
  • 将应用程序读取到内存之后,其所在的进程也创建起来了,此时通常会调用fork系统调用来创建子进程,系统调用的保存和恢复现场对应用程序的启动运行也有一定的影响. 通过CPU内部的存储器来快速保存现场和恢复
  • 系统调用前期处理完,接下来需要对子进程内部资源(地址空间、页表、打开文件列表等)进行初始化,传统的进程创建(传统UNIX),是把父进程的所有资源复制到子进程中,即把父进程的地址空间中的内容全部复制到子进程的地址空间中,既耗时又效率低; 如今针对fork创建进程,是采用了写时复制技术(COW),允许父子进程读相同的物理页,只要两者有一个进程试图写物理页,内核就把这个页的内容拷贝到一新物理页中, 并把这个新的物理页分配给正在写的进程,从而大大地提高了效率。
  • 进程创建完,就被作为可运行态进程放入运行队列中,若是没有其他IO请求或资源请求,就等待CPU资源,然后被执行,这里就该采用进程调度算法来进行进程的调度, 采用合适的调度算法可以使进程的性能提高

  • 在运行过程中,由于内存容量的限制,有时不可避免地会发生缺页异常,需要进行页面置换,从分配的物理页中选择一页换出去,再将需要的页从磁盘换进来,该如何选取被换出的页,也是一个影响程序性能的重要因素,如果页面置换算法选取不当,就会导致较大的缺页率,从而需要频繁地读取磁盘,换进换出。

实验总结分析报告:从系统的角度分析影响程序执行性能的因素

原文:https://www.cnblogs.com/hedyyu/p/14774028.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!