1. 64位平台下,用#progampack(4)或者编译器选项方法是否对性能有影响?
答案是肯定的。根据查询一些资料的结果,对性能有影响的原理为:在64位平台下,每次寻址取值都是要以8个字节的地址为单位进行,所以将int64_t的一个数据放在8的整数倍的内存地址上,则只要寻址一次就可以取值。否则需要通过两次寻址才能取得一个int64_t的值。
2. XX公司现有的代码是否存在内存不对齐导致大量内存浪费的情况?
我选取了xxxx.h, xxxx.h等声明很多结构体的代码来看。我们代码中并没有出现像单个的char型和int32_t或者int64_t混合使用的极端情况。大部分的情况下我们的结构体声明都是大量的int32_t,int64_t与字符数组共用,也就是说,这个时候如果有内存不对齐,只可能是int32_t,int64_t和字符数组对得不齐引起的。
但是在很多(至少5个)int32_t,int64_t和字符数组排成一个结构体的情况下,只要字符数组长度不要太短,内存实际上基本对齐的。有个比较简单的验证办法,就是用4字节对齐的编译选项重新编译一下我们的程序,然后对比一下修改先后程序运用占用的内存大小。
3. 根据内存对齐的原理,我们需要注意什么?
a. 在结构体声明中,避免将小型的数据char, bool与int32_t,int64_t这种大型的数据混合的使用,并且在意识到有内存不对齐的情况下,将隐式占用的内存显式定义,例如(这个问题在XX公司的代码当中不严重):
typedefstruct TAlignTest
{
int32_t nInt32A;
int64_t lInt64;
char cChar;
int32_t nInt32B;
bool bBool;
}AlignTest;
建议改为:
typedefstruct TAlignTest
{
char cChar;
bool bBool;
char szReserved[6];
int32_tnInt32A;
int32_tnInt32B;
int64_tlInt64;
}AlignTest;
b. 在结构体里面声明一个字符型数组,数组的长度建议声明成8的整数倍,。例如,xxxxx.h中:
struct CServDestinationData
{
int64_t lServId;
char szCalledNbr[21];
int32_t nCalledNbrLength;
int64_t timeEffDate;
int64_t timeExpDate;
int32_t nPricingPlanIdBuddy;
int32_t nMatchType;
char szEffAcctMonth[7];//生效月份
char szExpAcctMonth[7];//失效月份
};
这样的结构体定义隐式地占用了内存,并且会使人困惑,用户无法确定sizeof(CServDestinationData)等于多少(80)。建议改为:
struct CServDestinationData
{
int64_t lServId;
char szCalledNbr[24];
int32_t nCalledNbrLength;
int32_t nReserved;
int64_t timeEffDate;
int64_t timeExpDate;
int32_t nPricingPlanIdBuddy;
int32_t nMatchType;
char szEffAcctMonth[8];//生效月份
char szExpAcctMonth[8];//失效月份
};