V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
glogo
V2EX  ›  C

请教大家一个感受:内存对齐

  •  1
     
  •   glogo · 2016-02-29 18:17:22 +08:00 · 4497 次点击
    这是一个创建于 3218 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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
    通过里面的例子发现对齐并没有效果那么明显.....

    所有在这里向大伙儿请教下,使用了内存对齐给你的程序和工作带来了哪里飞一般的“感受”
    (如能附上例子更好了~)

    36 条回复    2016-03-27 16:49:21 +08:00
    itfanr
        1
    itfanr  
       2016-02-29 18:20:31 +08:00
    mark
    theoractice
        2
    theoractice  
       2016-02-29 18:56:30 +08:00   ❤️ 1
    矩阵乘法交换一下最后两个循环的顺序可以加速一倍以上。
    然而其实最快的还是 blas 库。。。
    imshawer
        3
    imshawer  
       2016-02-29 19:23:54 +08:00
    常识性知识点,很多计算机图书都会提到这一点,比如《深入理解计算机系统》。

    X86/X64 如果没对齐会通过额外的 CPU 周期矫正,某些架构 CPU 也会直接异常,在语言高度发展的今天可能大多数程序员都不会注意这个问题。
    glogo
        4
    glogo  
    OP
       2016-02-29 19:26:25 +08:00
    @imshawer 蟹蟹,请问你在工作当中有遇到这类的问题吗
    glogo
        5
    glogo  
    OP
       2016-02-29 19:34:48 +08:00
    @imshawer 可以举例下异常的情况么
    l6751902
        6
    l6751902  
       2016-02-29 19:41:35 +08:00
    ...........估计将近 10 年没关心过这个问题了。。。。。大概原因是开发 /个人时间是越来越值钱,而计算资源是越来越廉价
    imshawer
        7
    imshawer  
       2016-02-29 19:44:13 +08:00
    @glogo 常识嘛,写代码时注意就行了,比如 Itanium(IA-64) 架构貌似会直接异常,你可以查查。
    redsonic
        8
    redsonic  
       2016-02-29 19:48:35 +08:00   ❤️ 1
    @glogo mips 架构的 cpu 要求内存必须对齐,否则运行时会触发 bus error ,将一些代码编译到 mips 的时候会经常遇到。另外内存不对齐的话对一二级 cache 开销也比较大,我觉得在 x86/64 平台上内存对齐属于深度优化的范围,一般的代码并不敏感。但有一些还是非常重要的,比如内核里频繁访问的结构体尤其是 hash 结构 优化不优化差别还是很大的。
    ttycode
        9
    ttycode  
       2016-02-29 20:03:16 +08:00 via Android   ❤️ 1
    底层的接口,要么涉及到运算,要么涉及到 io ,才会这么明显。
    lion9527
        10
    lion9527  
       2016-02-29 20:46:24 +08:00
    只记得以前写 C 的时候注意结构体里对齐,其他的就没用过了。我是菜鸟~
    sujin190
        11
    sujin190  
       2016-02-29 22:22:49 +08:00
    其实还是没看懂这个怎么对其的,有人解释一下么?
    sinxccc
        12
    sinxccc  
       2016-02-29 23:08:52 +08:00
    尝试过往 MIPS 上移植代码的话就知道好处了…
    eliteYang
        13
    eliteYang  
       2016-02-29 23:15:14 +08:00   ❤️ 1
    我用对齐一般在网络通讯里,不对齐就会导致不同语言开发的收到的数据占用不正常,对不上
    for4
        14
    for4  
       2016-02-29 23:18:31 +08:00
    glogo
        15
    glogo  
    OP
       2016-02-29 23:40:47 +08:00
    @eliteYang 感谢,网络的例子我还没有遇到,可以分享下吗
    sinxccc
        16
    sinxccc  
       2016-02-29 23:46:35 +08:00
    @eliteYang 理论上来说除非是对性能要求非常极端,否则的话网络上传输的内容不应该跟平台的数据结构强耦合…
    msg7086
        17
    msg7086  
       2016-03-01 00:04:30 +08:00
    这么说吧。很多 avx2 指令集根本不吃没对齐的数据。你不好好对齐直接崩一脸。
    redsonic
        18
    redsonic  
       2016-03-01 00:09:35 +08:00   ❤️ 1
    @sinxccc 网络通信里面的对齐优化指的是底层代码中结构的 1 字节对齐,因为编译器会自动优化填充一些 padding ,使结构体里的每个成员按 4 字节或 8 字节对齐,结果接收端收到报文再放入结构的时候会错位。扒一下服务器的代码会看到附加 __attribute__ ((packed)) 属性的就是干这事的。
    ershisi
        19
    ershisi  
       2016-03-01 08:36:10 +08:00
    做 c 底层开发,做 socket 的基本上都需要对齐。然后对结构体的大小有严格的认识。如果是做较为上层的东西,对齐是不需要你考虑的。另外,印象中对齐是在编译阶段进行的。(两年不做 c 开发了, c 基本快忘记了。。。)
    linux40
        20
    linux40  
       2016-03-01 08:42:59 +08:00 via Android
    。。。原来默认是不对齐的?我以为写个 struct 就自动给你对齐了,难道不是吗, c++不是有个 alignof 吗。。。
    mko0okmko0
        21
    mko0okmko0  
       2016-03-01 08:58:13 +08:00
    这不是编译工具链该做的吗?
    我觉得代码层先做好逻辑,再谈优化或移植限制.
    suntus
        22
    suntus  
       2016-03-01 09:46:25 +08:00
    用 uthash 时遇到过,用 struct 做 key ,因为内存对齐的缘故,有些位没有正确赋值,会让这个 key 失效,解决办法是每次对 key 赋值前,都把内存归零,这样可以保证填充的位也都是 0
    testlc
        23
    testlc  
       2016-03-01 10:14:59 +08:00
    有时候 socket 结构体需要取消默认对齐方式,按 1 字节的对齐方式
    wadahana
        24
    wadahana  
       2016-03-01 10:21:26 +08:00
    arm 处理器 , 32 位长整型指针访问非 4 字节对齐的地址, 16 位整型指针访问奇数地址, 直接挂给你看。
    w2exzz
        25
    w2exzz  
       2016-03-01 12:24:09 +08:00 via Android
    Cache aligned 对 cache 做优化的时候也会对齐
    eliteYang
        26
    eliteYang  
       2016-03-01 12:57:01 +08:00   ❤️ 1
    @sinxccc 自定义协议包一般都有这种,特别是包头都需要的,包体一般都是序列化后的 string ,倒是无所谓了
    @glogo 随便找一个自定义包头通讯的 C++例子,就可以看到里面的用法,手上暂时没有开源的例子
    msg7086
        27
    msg7086  
       2016-03-01 13:22:06 +08:00
    @linux40 应该不分默认不默认吧。不显式申明的话编译器很可能自说自话去处理的。
    所以如果要精确控制结构体结构的话,要自己写清楚是否需要对齐。
    同样的如果要喂给 avx 系指令集的话,也要自己手动设置对齐到某个边界。
    miao1007
        28
    miao1007  
       2016-03-01 21:08:41 +08:00
    这个在通信设备上用的比较多,一般显式的使用 char[x] reserved 进行填充,一般是 4 字节对齐,性能提升是明显的。
    glogo
        29
    glogo  
    OP
       2016-03-02 00:56:50 +08:00
    @sinxccc 搜嘎,很可惜,我的工作中没有能进行这类的任务
    glogo
        30
    glogo  
    OP
       2016-03-02 00:59:39 +08:00
    @linux40 这个需要实际测试一下,我用 GCC 写的小程序 gcc -Wall 编译并不会自动对齐
    glogo
        31
    glogo  
    OP
       2016-03-02 01:01:22 +08:00
    @suntus uthash 这样做的考虑点有关性能方面的么?
    glogo
        32
    glogo  
    OP
       2016-03-02 01:05:30 +08:00
    @ershisi 听了各位的分享,感觉也是在做应用层的开发时不是很能有机会去关注到内存对齐,前人的铺垫帮我们做了很多,让我们能有更多的时间专注于业务
    glogo
        33
    glogo  
    OP
       2016-03-02 01:09:27 +08:00
    @wadahana 诶, ARM 上的话,我又联想到 Android 平台的指令集,这个有什么说法在里面吗, linux, android, arm....
    linux40
        34
    linux40  
       2016-03-02 10:03:30 +08:00 via Android
    @glogo c++呢, c++有一个 alignof 关键字,你写一个 struct 再 alignof 那个 struct 的话会返回 struct 的对齐长度。。。好像是这样。。。
    suntus
        35
    suntus  
       2016-03-02 14:15:46 +08:00
    @glogo 没有性能方面的,只是遇到过的一个需要注意内存对齐的地方了
    3dwelcome
        36
    3dwelcome  
       2016-03-27 16:49:21 +08:00 via Android
    你们都没用过 sse 吗?对齐是常识性问题。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2693 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 08:23 · PVG 16:23 · LAX 00:23 · JFK 03:23
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.