0%

1 存储技术

作为一名程序员,你必须了解存储器的层次结构,因为它对应用程序的性能有着巨大的影响。

  • 如果你的数据是在cpu寄存器上,那么指令执行期间在0个周期就能访问到
  • 如果是在高速缓存中,需要4-75个周期
  • 如果在主存,需要上百个周期
  • 如果是在磁盘,那么就需要大约几千万个周期,时间大概是毫秒级,比主存慢10万倍,比高速缓存慢100万倍

1.1 随机访问存储器

随机访问存储器(RAM)有两类:静态和动态。静态RAM(SRAM)比动态DRAM(DRAM)更快,但也更贵,因此SRAM一般集成在CPU上作为高速缓存,DRAM则作为主存。断电以后,DRAM和SRAM都会丢失它们的信息

访问主存:每次CPU和主存之间的数据传送都是通过一系列的步骤来完成,这些步骤称为总线事务读事务从主存传输数据到CPU,写事务从CPU传送数据到主存。总线是一组并行的导线,能携带地址、数据和控制信号。

阅读全文 »

1 导读

程序优化涉及的范围实在是太广了,几乎每个层面都可以进行优化,比如撰写<编译器友好型>以及<缓存友好型>的程序,针对不同的目标硬件平台还可能进行特定的优化,等等,优化的难点在于你需要对系统有充分理解,当然了在你做优化之前首先要保证原始程序功能正确(并且有回归测试),否则一切都是徒劳。

首先需要理解,哪些因素会影响程序的性能

阅读全文 »

内存对齐规则

在C/C++中的结构体或类,存在内存对齐问题。内存对齐是为了方便计算机进行寻址,优化寻址速度的一个措施,其代价是消耗不必要的内存空间。

内存对齐遵循以下规则:

  • 第一个成员在与结构体变量偏移量为0的地址处。
  • 其他成员变量都放在对齐数(成员的大小和默认对齐数的较小值)的整数倍的偏移地址处。
    • 对齐数=编译器默认的一个对齐数与该成员大小的较小值。(不同的编译器其默认对齐数不同,64位系统中VS默认的对齐数是8,在Linux中没有默认的对齐数)
    • 可以在程序开端声明#pragma pack(数字)来设置默认对齐值
  • 结构体总大小为最大对齐数(每个成员变量都有一个对齐数 )的整数倍。
  • 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。--->最大对齐数肯定不超过默认对齐数

示例:VS运行(默认对齐数为8)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
typedef struct test2
{
int a;//4-->8,占0,1,2,3地址处,后续补4,5,6,7
double c;//8,但由于其只能放在与首地址偏移量为8的地址上,因此4,5,6,7作为填补空缺,它从8存储
};

typedef struct testMemory
{
int a;//4-->8
long b;//8
char c;//1
struct test2 l;//16
};

cout <<sizeof(test2) << " " << sizeof(testMemory) << endl;

输出:
1
16 40

class类

在C++中,class与struct是相同的,除了:

  • 两者中如果不对成员不指定公私有,struct默认是公有的,class则默认是私有的

  • class默认是private继承, 而struct默认是public继承

因此,对于struct的对齐规则同样是class的对齐规则,在c++中,还必须注意在存在虚函数时类有一个虚表指针的情况:(在64位中指针大小为8字节,32为4字节)

1
2
3
4
5
6
7
8
9
 class my {
private:
int a;
double b;
char c;
virtual int m() { return 0; }
virtual int s(){return 0;}
};
//sizeof(my)为32:8+8+8+8

程序的机器级表示

在本章,会学习观察汇编代码和机器代码。说到汇编语言就不得不提编译器和汇编器。**编译器是基于编程语言规则、目标机器的指令集和操作系统遵循的惯例,经过一系列阶段如图:

gcc编译器以汇编代码的形式产生输出,然后gcc调用汇编器和链接器生成二进制机器文件和可执行文件。对于Linux机,可以使用 gcc -Og -S xxx.c来进行学习。因为参数-Og表明不进行优化,这可以让汇编代码尽可能地保持和C源码一样的顺序,位置,排列等。

阅读全文 »

Here's something encrypted, password is required to continue reading.
阅读全文 »

SSH(Secure Shell,安全外壳)是一种网络安全协议,通过加密和认证机制实现安全的访问和文件传输等业务。传统远程登录或文件传输方式,例如Telnet、FTP,使用明文传输数据,存在很多的安全隐患。随着人们对网络安全的重视,这些方式已经慢慢不被接受。SSH协议通过对网络数据进行加密和验证,在不安全的网络环境中提供了安全的登录和其他安全网络服务。作为Telnet和其他不安全远程shell协议的安全替代方案,目前SSH协议已经被全世界广泛使用,大多数设备都支持SSH功能。

阅读全文 »

7. GCC和gcc++编译器

7.1 gcc和 GCC是两个不同的东西
  • GCC:GNU Compiler Collection(GUN 编译器集合),它可以编译C、C++、JAV、Fortran、Pascal、Object-C、Ada等语言。
  • 因此gccGCC中的GUN C Compiler(C 编译器);g++GCC中的GUN C++ CompilerC++编译器)。二者都可以编译ccpp文件。只不过用gcc编译c++需要手动添加链接库
  • 在编译阶段,g++会调用gcc,对于c++代码,两者是等价的,但是因为gcc命令不能自动和C++程序使用的库联接,所以通常使用用g++来编译以求自动完成链接。所以对于C语言程序的编译,我们应该使用gcc 指令,而编译C++程序则推荐使用g++指令
阅读全文 »