如何在高速缓存边界对齐数据结构

celineshi 2006-08-23 02:29:36
原文地址:http://intel.csdn.net/ISN_J.aspx?action=JMP&pointid=396

挑战
确保每个同步变量都独自位于一个高速缓存行上。 正如我们在如何避免错误共享 中所讨论的那样,当将同步结构拉伸至高速缓存行的大小后,必须确保同步结构在高速缓存边界上对齐。


解决方案
利用下面给出的适当编码技术,将数据结构在高速缓存边界上对齐。 将同步结构拉伸为高速缓存行的大小并不能说是完全大功告成。您还需确保同步结构在高速缓存边界上对齐。同步变量不能与另一个同步结构位于相同的高速缓存行上,如果同步结构没有在高速缓存边界上对齐,则同步变量无法独自位于一个高速缓存行上。可以采用下面两种技术中的一种来执行对齐。

针对动态内存,采用如下代码片断:


struct syn_str { int s_variable; };

void *p = malloc ( sizeof (struct syn_str) + 127 );

syn_str * align_p = (syn_str *)( (((int) p) + 127) & -128 );



当使用英特尔 C/C++ 编译器时,也可采用下面的代码片断:


_declspec(align(128)) struct syn_str aligned_structure;

...全文
719 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
guinh3 2006-10-04
  • 打赏
  • 举报
回复
这个技术很使用,在我们的项目中需要使用很大的动态Double数组,而后进行计算,地址和Cache是否对其很重要,假如第一个不对齐,那后面的很多就会错位,那很明显算法的效率就会下降。
mathe 2006-09-28
  • 打赏
  • 举报
回复
SSE, MMX等指令都需要内存对齐。
对于普通代码,内存边界对齐也是有好处的,可以降低高速缓存(Cache)和内存交换数据的次数。

主要问题是在于Cache本身是分成很多Cache-Line,每条Cache-Line具有一定的长度,比如一般来说L1 Cache每条Cache Line长度在32个字节或64个字节;而L2的会更大,比如64个字节或128个字节。
用户每次访问地址空间中一个变量,如果不在Cache当中,那么就需要从内存中先将数据调入Cache中。
比如现在有个变量 int x;占用4个字节,它的起始地址是0x1234567F;那么它占用的内存范围就在
0x1234567F-0x12345682之间。如果现在Cache Line长度为32个字节,那么每次内存同Cache进行数据交换时,都必须取起始地址时32(0x20)倍数的内存位置开始的一段长度为32的内存同Cache Line进行交换.
比如0x1234567F落在范围0x12345660~0x1234567F上,但是0x12345680~0x12345682落在范围0x12345680~0x1234569F上,也就是说,为了将4个字节的整数变量0x1234567F~0x12345682装入Cache,我们必须调入两条Cache Line的数据。但是如果int x的起始地址按4的倍数对齐,比如是
0x1234567C~0x1234567F,那么必然会落在一条Cache Line上,所以每次访问变量x就最多只需要装入一条Cache Line的数据了。比如现在一般的malloc()函数,返回的内存地址会已经是8字节对齐的,这个就是为了能够让大部分程序有更好的性能。
而对于SSE,SSE2,MMX等,经常需要处理长度为32字节,64字节,128字节的数据;同样,将这些内存块的起始地址按对样长度对齐,可以减少访问Cache Line的次数。
rickfeng 2006-09-28
  • 打赏
  • 举报
回复
问一下,边界对齐的好处是什么?提升性能吗?
李世东 2006-09-15
  • 打赏
  • 举报
回复
谢谢
nkwesley 2006-08-30
  • 打赏
  • 举报
回复
好深奥啊
DentistryDoctor 2006-08-25
  • 打赏
  • 举报
回复
学习

567

社区成员

发帖
与我相关
我的任务
社区描述
英特尔® 边缘计算,聚焦于边缘计算、AI、IoT等领域,为开发者提供丰富的开发资源、创新技术、解决方案与行业活动。
社区管理员
  • 英特尔技术社区
  • shere_lin
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧