genius_platform软件平台开发】第十七讲:数据成员不同位置的访问效率

231 阅读2分钟

本文已参与好文召集令活动,点击查看: 后端、大前端双赛道投稿,2万元奖池等你挑战!

// 类的数据成员.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>

//////////////////////////////////////////////////////////////////////////
// 1. 验证数据成员不同位置访问效率
/*
如果成员相对于结构体或类开头的偏移量小于128,则访问数据成员的代码会更紧凑,因为该偏移量可以表示为8位有符号的数字。如果相对于结构体或类的开头的偏移量是128字节或更大,那么偏移量必须表示为一个32位数字(指令集在8位到32位之间没有偏移量)

 b的偏移量是400。任何通过指针或成员函数(如ReadB)访问b的代码,都需要将偏移量编码为32位数字。如果交换了a和b,则两者都可以通过编码为8位有符号数字的偏移量来访问,或者根本没有偏移量。这使代码更紧凑,以便更有效地使用Cache。因此,建议在结构或类声明中,大数组和其他大对象排在最后,最常用的数据成员排在前面。如果不能在前128个字节内包含所有数据成员,则将最常用的成员放在前128个字节中

 结论:
  1.1 查看汇编代码发现指令其实都是一样的

MyStruct obj;
memset(obj.a, 0, 2*1000);
  005C3C9C  push        7D0h
  005C3CA1  push        0
  005C3CA3  lea         eax,[obj]
  005C3CA9  push        eax
  005C3CAA  call        _memset (05C1078h)
  005C3CAF  add         esp,0Ch
obj.b = 1.0;
  005C3CB2  movsd       xmm0,mmword ptr ds:[5C5860h]
  005C3CBA  movsd       mmword ptr [ebp-18h],xmm0
obj.c = 1;
  005C3CBF  mov         dword ptr [ebp-10h],1

MyStruct2 obj2;
memset(obj2.a, 0, 2 * 1000);
  005C3CC6  push        7D0h
  005C3CCB  push        0
  005C3CCD  lea         eax,[ebp-0FC4h]
  005C3CD3  push        eax
  005C3CD4  call        _memset (05C1078h)
  005C3CD9  add         esp,0Ch
obj2.b = 2.0;
  005C3CDC  movsd       xmm0,mmword ptr ds:[5C5868h]
  005C3CE4  movsd       mmword ptr [obj2],xmm0
obj2.c = 2;
  005C3CEC  mov         dword ptr [ebp-0FC8h],2

*/

// 结构体1
struct MyStruct     
{
    short a[1000];
    double b;
    int c;
};

// 结构体2
struct MyStruct2
{
    double b;
    int c;
    short a[1000];
};

//////////////////////////////////////////////////////////////////////////
//
int _tmain(int argc, _TCHAR* argv[])
{
    MyStruct obj;
    memset(obj.a, 0, 2*1000);
    obj.b = 1.0;
    obj.c = 1;

    MyStruct2 obj2;
    memset(obj2.a, 0, 2 * 1000);
    obj2.b = 2.0;
    obj2.c = 2;

    system("pause");
	return 0;
}
`