遇君阁

前不见古人,后不见来者
念天地之悠悠,独怆然而涕下

  VC知识库BLOG :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 登录 ::
  26 随笔 :: 8 文章 :: 53 评论 :: 0 Trackbacks
<2008年5月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

留言簿(0)

随笔分类

随笔档案

文章分类

文章档案

相册

相关链接

搜索

最新评论

阅读排行榜

评论排行榜

字节对齐的目的是什么?
1.增加内存利用率
2.增加程序的运行效率
但这两点有时候在内存对齐时却是相互违背的。比如我们来对比下面的程序,在此之前声明一下我的环境,x86(P4),VC 2005:
程序1
#pragma pack(4)
class A
{
public:
 char a;
 int aa;

};

程序2
#pragma pack(1)
class B
{
public:
 char a;
 int aa;

};
类A的size是8,而B的size是5,A相对于B来说浪费了内存空间,但同时我们还要看看对于A和B中的成员aa,aa的地址在类A中是可以被4整除(即:addr(A::aa)%4=0),而aa在类B中由于内存对齐方式是1,所以aa的地址无法被4整除(即:addr(A::aa)%4!=0).那么由于在x86(32位)上,从无法被4整除的地址边界去访问变量,会影响效率,具体原因已经超出了本文的讨论范围,以后用另一篇文章讨论.这里只放一个测试用例,如果有兴趣的朋友可以运行一下(VC 2005):
测试用例1:
inline   unsigned   __int64   GetCycleCount(void)  
{  
      _asm         _emit   0x0F  
      _asm         _emit   0x31  
}

int _tmain(int argc, _TCHAR* argv[])
{
 long long l = 3000000000000;

 unsigned   __int64 begin = GetCycleCount();
 
 for(long long i = 1000000000; i > 0; i--)
 {
  // Empty the cache in CPU.
  l--;
  // Access the memory as the address can be divided by 4
  __asm
  {
   
   mov ecx,dword ptr [l]
  }
 }
 
 unsigned   __int64 end = GetCycleCount();
 printf("The elapse time is:%I64d\n", end - begin);
 return 0;
}
测试用例2:
inline   unsigned   __int64   GetCycleCount(void)  
{  
      _asm         _emit   0x0F  
      _asm         _emit   0x31  
}

int _tmain(int argc, _TCHAR* argv[])
{
 long long l = 3000000000000;

 unsigned   __int64 begin = GetCycleCount();
 
 for(long long i = 1000000000; i > 0; i--)
 {
  // Empty the cache in CPU.
  l--;
  // Access the memory as the address can not be divided by 4
  __asm
  {
   
   mov ecx,dword ptr [l+1]
  }
 }
 
 unsigned   __int64 end = GetCycleCount();
 printf("The elapse time is:%I64d\n", end - begin);
 return 0;
}
比较测试用例1与测试用例2打印出来的时间,你就可以从直观上得到访问奇地址时效率上的损失.
所以我的结论是:
在使用字节对齐时,请仔细考虑你要的是效率还是要的是内存,并在写程序时注意。

posted on 2008-05-07 11:28 遇君阁 阅读(1561) 评论(4)  编辑 收藏

评论

# re: 请仔细权衡内存对齐 2008-05-14 18:52 gaoqing000
这是什么程序啊,能运行吗

# re: 请仔细权衡内存对齐 2008-05-14 18:55 gaoqing000
哦,看了, 写行好

# re: 请仔细权衡内存对齐 2008-05-14 18:58 gaoqing000
编译了一下
全是错,在vc6下试的
inline unsigned __int64 GetCycleCount(void)
{
_asm _emit 0x0F
_asm _emit 0x31
}

int _tmain(int argc, _TCHAR* argv[])
{
long long l = 3000000000000;

unsigned __int64 begin = GetCycleCount();

for(long long i = 1000000000; i > 0; i--)
{
// Empty the cache in CPU.
l--;
// Access the memory as the address can not be divided by 4
__asm
{

mov ecx,dword ptr [l+1]
}
}

unsigned __int64 end = GetCycleCount();
printf("The elapse time is:%I64d\n", end - begin);
return 0;
}



# re: 请仔细权衡内存对齐 2008-05-14 18:58 gaoqing000
Compiling...
ss.cpp
d:\mytestprogram\p56\ss.cpp(5) : warning C4035: 'GetCycleCount' : no return value
d:\mytestprogram\p56\ss.cpp(7) : error C2061: syntax error : identifier '_TCHAR'
d:\mytestprogram\p56\ss.cpp(9) : error C2632: 'long' followed by 'long' is illegal
d:\mytestprogram\p56\ss.cpp(9) : warning C4305: 'initializing' : truncation from 'const __int64' to 'long'
d:\mytestprogram\p56\ss.cpp(9) : warning C4309: 'initializing' : truncation of constant value
d:\mytestprogram\p56\ss.cpp(13) : error C2632: 'long' followed by 'long' is illegal
d:\mytestprogram\p56\ss.cpp(26) : error C2065: 'printf' : undeclared identifier

标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]