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

想问个内存写入的问题

  •  
  •   voidmnwzp ·
    NullpointerW · 2022-08-23 02:44:13 +08:00 via iPhone · 2431 次点击
    这是一个创建于 606 天前的主题,其中的信息可能已经有所发展或是发生改变。

    比如一个 32 位 cpu 字长为 4 一次读取 32 位 假设定义了两个变量 a int16 0x0-0x1 b int32 0x2-0x5 赋值 a=1 如果 cpu 是一次性写入 32 位的 也就是说是写入范围是 0x0-0x3 这部分内存相当于覆盖了一部分 b 的数据 按道理说写入 a 会造成 b 的改变 但实际并不会也就说 cpu 写入可以不按字长来?

    15 条回复    2022-08-24 09:51:52 +08:00
    msg7086
        1
    msg7086  
       2022-08-23 03:09:29 +08:00
    CPU 也可以先读取内存,修改数据,然后再回写。
    akira
        2
    akira  
       2022-08-23 03:37:58 +08:00
    CPU 除了 32 位的操作指令,还有 16 位和 8 位的。 这种基础的需求人家还是会考虑到的。

    例如 赋值 a = 1
    他生成的指令 可能是
    mov ax , 1
    mov [a] , ax
    ryd994
        3
    ryd994  
       2022-08-23 04:17:06 +08:00 via Android
    你这个问题和前两天问内存为什么需要对齐的,就是同一个问题的两面
    dingwen07
        4
    dingwen07  
       2022-08-23 06:34:13 +08:00
    小于字长的变量应该还是会分配一个字的内存空间
    mingl0280
        5
    mingl0280  
       2022-08-23 06:37:50 +08:00   ❤️ 1
    首先,x86_64 的 CPU 读多少并不按“32 位”或“64 位”这个字长来的。这个是“最大可以处理 N 位”的意思。
    然后,一般来说,现在的 CPU 读取的最小单位是 8 位(一个字节)。
    最后,内存对齐跟这事没关系。
    julyclyde
        6
    julyclyde  
       2022-08-23 08:29:48 +08:00
    你不能随随便便假定“也就是”写入范围从 0 到 3
    cpstar
        7
    cpstar  
       2022-08-23 08:37:04 +08:00
    如果这么一个简单错误就产生了,那 CPU 不用干活了。天天就在覆盖写数据。

    两种方法,编译器和运行时。
    编译器阶段,不可能产生 b 从 0x2 开始,直接 b 也是 4 字节对齐,a 虽然是 int16 ,但是占用了 0x0-0x3 ,只用 0x2/0x3 存储(大端情况)。当然了这个很浪费。
    所以采用运行时方法,其实还是编译器在处理指令的之后,读取半字用用半字的指令,读取全字用全字的指令。

    大概以上这个意思,为准 100%准确。
    BingoXuan
        8
    BingoXuan  
       2022-08-23 09:27:13 +08:00
    读写多少和 cpu 无关,和内存总线有关,一般大小都是 2 的次方。
    ch2
        9
    ch2  
       2022-08-23 09:52:55 +08:00
    最小写入单位是一个 char 8 位,不是 32 位
    leonhao
        10
    leonhao  
       2022-08-23 09:57:34 +08:00
    32 位只是提高效率一次批量多读几个字节的数据,减少寻址,定位的时间,不是只能读 32 位。。。
    yolee599
        11
    yolee599  
       2022-08-23 09:59:56 +08:00
    你这个假设是错误的,变量的在内存的分布不会按照你假设的来分布。有的编译器会自动做对齐操作。
    https://s1.ax1x.com/2022/08/23/v6IAts.png
    有的 C 语言库为了提高执行效率就有很多 align 宏,手动做对齐操作。
    yanqiyu
        12
    yanqiyu  
       2022-08-23 10:22:18 +08:00
    x86 内存操作的单位是一个 cacheline ,就算你只操作 1bit ,CPU 也得读写整个 cacheline
    Tanix2
        13
    Tanix2  
       2022-08-23 13:27:55 +08:00
    @yanqiyu 内存和 cache 之间是以 line 为单位,但是 CPU 和 cache 间不是
    Arnie97
        14
    Arnie97  
       2022-08-24 00:57:10 +08:00
    以 amd64 处理器为例,除了 rax ,还有 eax ax ah al…
    GrayXu
        15
    GrayXu  
       2022-08-24 09:51:52 +08:00
    后面的评论都有点跑题,答案就是一楼的 read modify write 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   881 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 77ms · UTC 22:00 · PVG 06:00 · LAX 15:00 · JFK 18:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.