深入计算机系统看性能优化

这篇具有很好参考价值的文章主要介绍了深入计算机系统看性能优化。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一.引言

“性能优化”,从计算机诞生之初就一直伴随着计算机技术的发展,直到现在。将来也必定不会消失。这是因为每个人都会追求性价比,花最少的钱,办最多的事。生活中也一样,就比如说泡茶,但凡有点常识的人都不会先洗茶杯,再去烧水,而是先去烧水,在等水开的过程中,去做洗茶杯等工作。这也是一种优化。

本篇尝试带大家从计算机系统的角度,简单介绍一下几种性能优化的原理和方法,抛砖引玉,供大家参考。

二.访问寄存器代替内存引用

我们先看一个例子:

有这么两个程序:它们的目的就是将数组x中的数,按照下标累加到数组y中,最后在把数组y中的数据累加到一个数dest里面。为了验证效果,我们将这个过程重复10000遍。

深入计算机系统看性能优化,性能优化

                      Prog 1                                                Prog2

这两个程序的区别就在Prog2中红框里面的内容。那么哪个程序运行的更快呢?

话不多说,我们看实际的结果:

深入计算机系统看性能优化,性能优化

深入计算机系统看性能优化,性能优化

这里为了说明效果,我们编译的时候,并没有采用优化(编译优化,确实可以提高程序运行的效率,但是过高的编译优化等级会有一定的副作用,另外编译器优化也具有一定的局限性,高效的代码仍然应该是我们追求的目标)。可以看到,Prog2要明显比Prog1快。

要想理解上面的例子,我们必须先介绍一下寄存器和汇编代码的相关知识:

1.寄存器

CPU内部用来存放数据的一些小型存储区域, 注意寄存器是在CPU内部,受限于CPU的物理尺寸,寄存器数量不会太多。我们只需要记住两点:

1)  寄存器和CPU的L1 cache相比,速度虽然还在一个数量级,但是L1 cache的访问速度还是要慢几倍。具体的数据见下文表2

2)  CPU只能从寄存器直接取数据或者指令,如果取不到,获取的顺序是L1->L2->L3->主存->磁盘。

从下文表2中可以看出,如果cpu的cache访问miss了,性能损失还是很大的。如果内存里面再miss了,那对性能来说不亚于一场灾难了。

计算机访问速度分级:

表1  时间单位

深入计算机系统看性能优化,性能优化

以3.3GHz的CPU为例:

表2  系统的各种延时

深入计算机系统看性能优化,性能优化

正如你所见,CPU周期的时间非常短,这段时间,光的速度大约只能走0.5米。想象一下,是不是非常震撼?

x86-64 CPU的整数寄存器:

深入计算机系统看性能优化,性能优化

我们无需刻意去记住这些寄存器的名称,不同架构的寄存器的数量和名称也不一样,我们只要知道他们是cpu内部的效率极高的存储单元即可。

回到前面的例子,为什么Prog2要比Prog1快,是因为Prog2里面用DEST这个局部变量代替了*dest。DEST是一个局部变量,在汇编指令里是直接访问寄存器,而*dest则需要去访问内存cache。

2.汇编代码简介

说到汇编语言的产生,首先要讲一下机器语言。机器语言是机器指令的集合。机器指令展开来讲就是一台机器可以正确执行的命令。电子计算机的机器指令是一列二进制数字。计算机将之转变为一列高低电平,以使计算机的电子器件受到驱动,进行运算。

上面所说的计算机指的是可以执行机器指令,进行运算的机器。这是早期计算机的概念。在我们常用的PC机中,有一个芯片来完成上面所说的计算机的功能。这个芯片就是我们常说的CPU(Central Processing Unit,中央处理单元)。每一种微处理器,由于硬件设计和内部结构的不同,就需要用不同的电平脉冲来控制,使它工作。所以每一种微处理器都有自己的机器指令集,也就是机器语言。

早期的程序设计均使用机器语言。程序员们将用0, 1数字编成的程序代码打在纸带或卡片上,1打孔,0不打孔,再将程序通过纸带机或卡片机输入计算机,进行运算。这样的机器语言由纯粹的0和1构成,十分复杂,不方便阅读和修改,也容易产生错误。

深入计算机系统看性能优化,性能优化

程序员们很快就发现了使用机器语言带来的麻烦(何止是麻烦,简直令人发狂),它们难于辨别和记忆,给整个产业的发展带来了障碍,于是汇编语言产生了。

汇编语言的主体是汇编指令。汇编指令和机器指令的差别在于指令的表示方法上。汇编指令是机器指令便于记忆的书写格式。

我们举个例子看下:

源代码:

深入计算机系统看性能优化,性能优化

汇编代码和机器码:

深入计算机系统看性能优化,性能优化

可以看到汇编代码,好歹还有几个能猜出意思的单词。

有没有觉得现在的程序员还是挺幸福的。

3.汇编指令简介

汇编语言是计算机语言的一种,是一种低级语言。相比高级语言,汇编语言更接近底层硬件,使用更加直接,效率更高。但相对而言,汇编语言更加复杂,语法更加严格。

  • 操作数指示符:

大多数指令有一个或多个操作数,指示出执行一个操作中要使用的源数据值。

操作数一般可以分为三类:

立即数

寄存器

内存引用

深入计算机系统看性能优化,性能优化

  • 数据传送指令:

最频繁使用的指令,负责将数据从一个位置复制到另一个位置。

例如:

mov %rbx, %rax  : 将rbx寄存器的值移动到rax寄存器

mov %rbx, (%rax) : 将rbx寄存器的值移动到rax寄存器所表示的内存地址中

以及mov指令的一些扩展指令: movb, movw, movl, movq等等

  • 压入和弹出栈数据

将数据压入程序栈中,以及从程序栈中弹出数据。

push %rbp : 将%rbp寄存器的值压入程序栈指针指向的位置

pop %rbp : 将栈指针指向的数据弹出,放入%rbp寄存器

  • 算数和逻辑操作

深入计算机系统看性能优化,性能优化

  • 跳转指令

导致执行切换到程序中一个全新的位置

jmp %rax 用寄存器%rax中的值作为跳转目标

jmp是无条件跳转,还有一些条件跳转指令,有兴趣的同学可以查一下资料。

  • 比较和测试指令

比较指令CMP,只设置条件码,不更新目的寄存器,其余的行为和SUB指令一致

测试指令TEST,只设置条件码,不更新目的寄存器,其余的行为和ADD指令一致

更多详细的内容,可以通过相关书籍进行系统性的了解,鉴于篇幅,就不多介绍了。

让我们回到刚才的例子,可以看到由于把内存引用替换成了访问寄存器,程序性能就有了明显的提升。

三.帮助提高CPU分支跳转的正确率

我们还是先看一个例子:

深入计算机系统看性能优化,性能优化

看上面的两个函数,它们都是calloc一个全零数组x(这里不能直接用数组赋值,否则编译器会足够聪明进行自动的优化),遍历x中的每个数,如果等于0,执行分支A,否则执行分支B。

唯一的不同就是在分支判断的时候,prog2.c加了likely。我们先看下实际的结果如何:

深入计算机系统看性能优化,性能优化

深入计算机系统看性能优化,性能优化

可以看出,加了likely的prog2,明显用时变短。原因何在?

为了理解上面的例子,我们先介绍CPU流水线相关知识:

3.1. CPU流水线简介

CPU流水线是一种使用多级缓存来提高处理器性能的技术。它是指将CPU操作分为多个阶段,每个阶段单独完成一个操作,然后将结果传递给下一个阶段,以此类推。每个阶段都有一个独立的部件,并且所有部件都能同时处理不同的指令。现代CPU都会采用这种技术来提高CPU的运行效率。

CPU流水线通常包括以下五个阶段:

1)取指令(Instruction fetch):从存储器中读取指令。

2)指令译码(Instruction decode):将指令转换为可执行的指令。

3)执行指令(Instruction execute):执行指令的操作。

4)写回(Write back):将执行指令得到的结果写回内存中。

5)更新程序计数器(Update program counter):将程序计数器加1,使它指向下一个指令。

举个简单的例子:

我们假设每一个步骤执行时间都是一个时钟周期,那么一条指令执行需要3个时钟周期

深入计算机系统看性能优化,性能优化

CPU 执行指令的3个时钟周期里,取值单元只在第一个时钟周期里工作,其余两个时钟周期都处于空闲状态,其它两个执行单元也是如此,效率太低了。

解决方法就是引入流水线,引入流水线工作模式后可以看到,除了刚开始第一个时钟周期大家还可以偷懒外,其余的时间都不会闲着

深入计算机系统看性能优化,性能优化

CPU流水线的优点是可以同时执行多个指令,从而提高了处理器的效率。但它也存在一些问题,例如数据相关性(Data dependency)和控制相关性(Control dependency),这些问题可能导致流水线停滞,降低CPU的性能。

执行的程序指令如果是顺序结构,没有中断或跳转,流水线确实可以提高执行效率。但是当程序指令中存在跳转、分支结构时,下面预取的指令可能就要全部丢掉了,需要到要跳转的地方重新取指令执行。一般来说分支预测错误的处罚大约是19个时钟周期。(具体计算方法这里不做详细介绍了)。

我们看下前面提到的例子汇编出来的结果:

深入计算机系统看性能优化,性能优化

prog2,这里汇编是”jne”,意思是如果判断结果不为0,就跳转到地址 800 的地方执行。我们知道这里的判断一直是0。所以,cpu指令顺序向下执行,并不会发生预判错误,预取的指令也不会丢弃。这样就不会遭到分支预测错误的惩罚,效率会提高。

所以有些情况下,当我们根据实际的情况可以判断出哪条分支的可能性更高的时候,我们就可以站在上帝视角给予一定的提示,这样就可以降低分支预测错误,减少CPU的无用功了,从而可以有效的提高性能,同时也节省了功耗。

四.总结

从计算机系统的角度来看,性能优化的几个思考方向:

1. 尽可能高效的获取数据

2. 尽可能减少CPU的无用功。

3. 尽可能在有限的时间内,让CPU干更多的有效的事情。

4. 完成同样的工作任务,尽可能的让CPU少做事。

参考资料:

1.《深入理解计算机系统》作者:【美】兰德尔E.布莱恩特 【美】大卫R.奥哈拉伦

2.《性能之巅》作者:【美】 Brendan Gregg

3. CSND博客:宋宝华:深入理解cache对写好代码至关重要

超详细!Linux内核内存规整详解

关于Ultra HDR Image的那些事

多图文教你看懂单个图层的绘制流程

深入计算机系统看性能优化,性能优化

长按关注内核工匠微信

Linux内核黑科技| 技术文章| 精选教程文章来源地址https://www.toymoban.com/news/detail-761528.html

到了这里,关于深入计算机系统看性能优化的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 计算机体系结构基础知识介绍之缓存性能的十大进阶优化之编译器优化和硬件预取(六)

    处理器和主内存之间不断扩大的性能差距促使编译器编写者仔细检查内存层次结构,看看编译时优化是否可以提高性能。再次,研究分为指令缺失的改进和数据缺失的改进。接下来介绍的优化可以在许多现代编译器中找到。 有些程序具有嵌套循环,以非连续的顺序访问内存中

    2024年02月12日
    浏览(69)
  • 计算机体系结构基础知识介绍之缓存性能的十大进阶优化之非阻塞缓存(四)

    对于允许乱序执行的流水线计算机,处理器不需要因数据高速缓存未命中而停止。 例如,处理器可以继续从指令高速缓存获取指令,同时等待数据高速缓存返回丢失的数据。 非阻塞高速缓存或无锁高速缓存允许数据高速缓存在未命中期间继续提供高速缓存命中,从而增强了

    2024年02月12日
    浏览(40)
  • 实验4 Cache性能分析【计算机系统结构】

    2023-6-16 21:19:13 以下内容源自《【计算机系统结构】》 仅供学习交流使用 实验3 Tomasulo算法【计算机系统结构】 (1)加深对Cache的基本概念、基本组织结构以及基本工作原理的理解。 (2)掌握Cache容量、相联度、块大小对Cache性能的影响。 (3)掌握降低Cache不命中率的各种方法。 采用

    2024年02月09日
    浏览(79)
  • 计算机体系结构基础知识介绍之缓存性能的十大进阶优化之小型且简单的一级缓存(二)

    缓存是一种高速的存储器,用于存放处理器经常访问的数据和指令。缓存的组织方式有多种,其中一种是按照不同的关联度(associativity)来划分。关联度表示一个缓存块(block)可以放在缓存中的位置数。关联度越高,缓存中可以容纳的不同块的数量越多,从而减少了冲突不命中

    2024年02月13日
    浏览(45)
  • 深入理解计算机系统(13)_存储器层次结构

    第一章 计算机的基本组成 1. 内容概述 2. 计算机基本组成 第二章 计算机的指令和运算 3. 计算机指令 4. 程序的机器级表示 5. 计算机运算 6. 信息表示与处理 第三章 处理器设计 7. CPU 8. 处理器体系结构 9. 优化程序性能 10. 其他处理器 第四章 存储器和IO系统 11. 存储器的层次结构

    2024年02月16日
    浏览(35)
  • 《深入理解计算机系统》Lab2-Bomblab

    这篇文章主要记录了我做bomblab的过程,希望能给你一些灵感 本次实验为 熟悉汇编程序 及其 调试方法 的实验。 实验内容包含2个文件:bomb(可执行文件)和bomb.c(c源文件)。 实验主题内容为: 程序运行在linux环境中。程序运行中有6个关卡(6个phase),每个phase需要用户在

    2024年02月04日
    浏览(43)
  • 《深入理解计算机系统(CSAPP)》第8章 异常控制流 - 学习笔记

    写在前面的话:此系列文章为笔者学习CSAPP时的个人笔记,分享出来与大家学习交流,目录大体与《深入理解计算机系统》书本一致。因是初次预习时写的笔记,在复习回看时发现部分内容存在一些小问题,因时间紧张来不及再次整理总结,希望读者理解。 《深入理解计算机

    2024年02月08日
    浏览(66)
  • 虚拟飞控计算机:飞行控制系统验证与优化的利器

    随着航空技术的飞速发展,飞行控制系统作为飞机的心脏,全面负责监测、调整和维持飞行器的姿态、航向、高度等参数,用以确保飞行的安全和稳定。为了满足这些要求,现代飞控系统通常采用先进的处理器和外设来确保其高效、稳定的运行。 ▲C919模拟驾驶舱   然而,在

    2024年02月19日
    浏览(43)
  • 《深入理解计算机系统(CSAPP)》第3章 程序的机器级表示 - 学习笔记

    写在前面的话:此系列文章为笔者学习CSAPP时的个人笔记,分享出来与大家学习交流,目录大体与《深入理解计算机系统》书本一致。因是初次预习时写的笔记,在复习回看时发现部分内容存在一些小问题,因时间紧张来不及再次整理总结,希望读者理解。 《深入理解计算机

    2024年02月07日
    浏览(61)
  • 《深入理解计算机系统(CSAPP)》第6章 存储器层次结构 - 学习笔记

    写在前面的话:此系列文章为笔者学习CSAPP时的个人笔记,分享出来与大家学习交流,目录大体与《深入理解计算机系统》书本一致。因是初次预习时写的笔记,在复习回看时发现部分内容存在一些小问题,因时间紧张来不及再次整理总结,希望读者理解。 《深入理解计算机

    2024年02月06日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包