Nginx 中有一个宏: ngx_align_ptr ,定义如下:
(u_char *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1))
然后好奇的 google 了,发现这篇文章 http://oopschen.github.io/article/2013-09-01/cpu-cacheline.html
通过里面的例子发现对齐并没有效果那么明显.....
所有在这里向大伙儿请教下,使用了内存对齐给你的程序和工作带来了哪里飞一般的“感受”
(如能附上例子更好了~)
1
itfanr 2016-02-29 18:20:31 +08:00
mark
|
2
theoractice 2016-02-29 18:56:30 +08:00 1
矩阵乘法交换一下最后两个循环的顺序可以加速一倍以上。
然而其实最快的还是 blas 库。。。 |
3
imshawer 2016-02-29 19:23:54 +08:00
常识性知识点,很多计算机图书都会提到这一点,比如《深入理解计算机系统》。
X86/X64 如果没对齐会通过额外的 CPU 周期矫正,某些架构 CPU 也会直接异常,在语言高度发展的今天可能大多数程序员都不会注意这个问题。 |
6
l6751902 2016-02-29 19:41:35 +08:00
...........估计将近 10 年没关心过这个问题了。。。。。大概原因是开发 /个人时间是越来越值钱,而计算资源是越来越廉价
|
8
redsonic 2016-02-29 19:48:35 +08:00 1
@glogo mips 架构的 cpu 要求内存必须对齐,否则运行时会触发 bus error ,将一些代码编译到 mips 的时候会经常遇到。另外内存不对齐的话对一二级 cache 开销也比较大,我觉得在 x86/64 平台上内存对齐属于深度优化的范围,一般的代码并不敏感。但有一些还是非常重要的,比如内核里频繁访问的结构体尤其是 hash 结构 优化不优化差别还是很大的。
|
9
ttycode 2016-02-29 20:03:16 +08:00 via Android 1
底层的接口,要么涉及到运算,要么涉及到 io ,才会这么明显。
|
10
lion9527 2016-02-29 20:46:24 +08:00
只记得以前写 C 的时候注意结构体里对齐,其他的就没用过了。我是菜鸟~
|
11
sujin190 2016-02-29 22:22:49 +08:00
其实还是没看懂这个怎么对其的,有人解释一下么?
|
12
sinxccc 2016-02-29 23:08:52 +08:00
尝试过往 MIPS 上移植代码的话就知道好处了…
|
13
eliteYang 2016-02-29 23:15:14 +08:00 1
我用对齐一般在网络通讯里,不对齐就会导致不同语言开发的收到的数据占用不正常,对不上
|
17
msg7086 2016-03-01 00:04:30 +08:00
这么说吧。很多 avx2 指令集根本不吃没对齐的数据。你不好好对齐直接崩一脸。
|
18
redsonic 2016-03-01 00:09:35 +08:00 1
@sinxccc 网络通信里面的对齐优化指的是底层代码中结构的 1 字节对齐,因为编译器会自动优化填充一些 padding ,使结构体里的每个成员按 4 字节或 8 字节对齐,结果接收端收到报文再放入结构的时候会错位。扒一下服务器的代码会看到附加 __attribute__ ((packed)) 属性的就是干这事的。
|
19
ershisi 2016-03-01 08:36:10 +08:00
做 c 底层开发,做 socket 的基本上都需要对齐。然后对结构体的大小有严格的认识。如果是做较为上层的东西,对齐是不需要你考虑的。另外,印象中对齐是在编译阶段进行的。(两年不做 c 开发了, c 基本快忘记了。。。)
|
20
linux40 2016-03-01 08:42:59 +08:00 via Android
。。。原来默认是不对齐的?我以为写个 struct 就自动给你对齐了,难道不是吗, c++不是有个 alignof 吗。。。
|
21
mko0okmko0 2016-03-01 08:58:13 +08:00
这不是编译工具链该做的吗?
我觉得代码层先做好逻辑,再谈优化或移植限制. |
22
suntus 2016-03-01 09:46:25 +08:00
用 uthash 时遇到过,用 struct 做 key ,因为内存对齐的缘故,有些位没有正确赋值,会让这个 key 失效,解决办法是每次对 key 赋值前,都把内存归零,这样可以保证填充的位也都是 0
|
23
testlc 2016-03-01 10:14:59 +08:00
有时候 socket 结构体需要取消默认对齐方式,按 1 字节的对齐方式
|
24
wadahana 2016-03-01 10:21:26 +08:00
arm 处理器 , 32 位长整型指针访问非 4 字节对齐的地址, 16 位整型指针访问奇数地址, 直接挂给你看。
|
25
w2exzz 2016-03-01 12:24:09 +08:00 via Android
Cache aligned 对 cache 做优化的时候也会对齐
|
26
eliteYang 2016-03-01 12:57:01 +08:00 1
|
27
msg7086 2016-03-01 13:22:06 +08:00
@linux40 应该不分默认不默认吧。不显式申明的话编译器很可能自说自话去处理的。
所以如果要精确控制结构体结构的话,要自己写清楚是否需要对齐。 同样的如果要喂给 avx 系指令集的话,也要自己手动设置对齐到某个边界。 |
28
miao1007 2016-03-01 21:08:41 +08:00
这个在通信设备上用的比较多,一般显式的使用 char[x] reserved 进行填充,一般是 4 字节对齐,性能提升是明显的。
|
32
glogo OP @ershisi 听了各位的分享,感觉也是在做应用层的开发时不是很能有机会去关注到内存对齐,前人的铺垫帮我们做了很多,让我们能有更多的时间专注于业务
|
33
glogo OP @wadahana 诶, ARM 上的话,我又联想到 Android 平台的指令集,这个有什么说法在里面吗, linux, android, arm....
|
34
linux40 2016-03-02 10:03:30 +08:00 via Android
@glogo c++呢, c++有一个 alignof 关键字,你写一个 struct 再 alignof 那个 struct 的话会返回 struct 的对齐长度。。。好像是这样。。。
|
36
3dwelcome 2016-03-27 16:49:21 +08:00 via Android
你们都没用过 sse 吗?对齐是常识性问题。
|