相关疑难解决方法(0)

现代x86硬件可以不将单个字节存储到内存中吗?

说到C++的并发内存模型,Stroustrup的C++编程语言,第4版,第1节.41.2.1,说:

...(像大多数现代硬件一样)机器无法加载或存储任何小于单词的东西.

但是,我的x86处理器,几年前,可以存储小于一个字的对象.例如:

#include <iostream>
int main()
{
    char a =  5;
    char b = 25;
    a = b;
    std::cout << int(a) << "\n";
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果没有优化,GCC将其编译为:

        [...]
        movb    $5, -1(%rbp)   # a =  5, one byte
        movb    $25, -2(%rbp)  # b = 25, one byte
        movzbl  -2(%rbp), %eax # load b, one byte, not extending the sign
        movb    %al, -1(%rbp)  # a =  b, one byte
        [...]
Run Code Online (Sandbox Code Playgroud)

评论是由我提出的,但是汇编是由GCC提出的.当然,它运行良好.

显然,我不明白Stroustrup在谈到硬件可以加载和存储任何小于一个单词的内容时所说的内容.据我所知,我的计划什么也不做,但加载和存储对象小于一个字的.

C++对零成本,硬件友好的抽象的彻底关注使C++与其他易于掌握的编程语言区别开来.因此,如果Stroustrup在公交车上有一个有趣的信号心理模型,或者有其他类似的东西,那么我想了解Stroustrup的模型.

什么 Stroustrup谈论,拜托?

更长时间的背景声明 …

c++ concurrency x86 assembly memory-model

25
推荐指数
2
解决办法
1869
查看次数

为什么GCC不使用部分寄存器?

write(1,"hi",3)在linux上反汇编,gcc -s -nostdlib -nostartfiles -O3结果如下:

ba03000000     mov edx, 3 ; thanks for the correction jester!
bf01000000     mov edi, 1
31c0           xor eax, eax
e9d8ffffff     jmp loc.imp.write
Run Code Online (Sandbox Code Playgroud)

我不是到编译器的开发,但由于移动到这些寄存器的每一个值是恒定的和已知的编译时间,我很好奇,为什么不GCC使用dl,dilal来代替.也许有人会说,此功能不会让任何性能上的差异,但有一个在之间的可执行文件的大小有很大的区别mov $1, %rax => b801000000,并mov $1, %al => b001当我们谈论数千寄存器的程序访问.如果软件的优雅部分不仅体积小,它确实会对性能产生影响.

有人可以解释为什么"海湾合作委员会决定"它无所谓?

x86 assembly gcc x86-64

13
推荐指数
2
解决办法
1655
查看次数

有没有现代/古老的CPU /微控制器,其中缓存的字节存储实际上比字存储慢?

一个普遍的说法是,缓存中的字节存储可能导致内部读 - 修改 - 写周期,或者与存储完整寄存器相比会损害吞吐量或延迟.

但我从未见过任何例子.没有x86 CPU是这样的,我认为所有高性能CPU也可以直接修改缓存行中的任何字节.一些微控制器或低端CPU是否有不同之处,如果它们有缓存的话?

(我不计算字可寻址的机器,或者字节可寻址但没有字节加载/存储指令的Alpha.我说的是ISA本身支持的最窄的存储指令.)

在我的研究中回答现代x86硬件可以不将单个字节存储到内存中吗?,我发现Alpha AXP省略字节存储的原因假设它们被实现为真正的字节存储到缓存中,而不是包含字的RMW更新.(因此,它会使L1d缓存的ECC保护更加昂贵,因为它需要字节粒度而不是32位).

所有现代架构(早期Alpha除外)都可以对不可缓存的内存(而不是RMW周期)进行真正的字节加载/存储,这对于为具有相邻字节I/O寄存器的设备编写设备驱动程序是必需的.(例如,使用外部启用/禁用信号来指定更宽总线的哪些部分保存实际数据,例如此ColdFire CPU /微控制器上的2位TSIZ(传输大小),或者像PCI/PCIe单字节传输,或者像DDR一样SDRAM控制信号掩盖选定的字节.)

对于微控制器设计,可能需要在缓存中为字节存储执行RMW循环,即使它不是针对像Alpha这样的SMP服务器/工作站的高端超标量流水线设计?

我认为这种说法可能来自可以用字寻址的机器.或者来自未对齐的32位存储,需要在许多CPU上进行多次访问,并且人们错误地将其从一般存储到字节存储.


为了清楚起见,我希望到同一地址的字节存储循环将在每次迭代中以与字存储循环相同的周期运行.因此,对于填充阵列,32位存储可以比8位存储快4倍.(也许如果少了32位门店饱和的内存带宽,但8位店家没有.)但是,除非字节存储有一个额外的惩罚,你不会得到超过4倍的速度差.(或者无论宽度是多少).

而我在谈论asm.一个好的编译器会自动向量化C中的字节或int存储循环,并使用更宽的存储或目标ISA上的最佳存储.

; x86-64 NASM syntax
mov   rdi, rsp
; RDI holds at a 32-bit aligned address
mov   ecx, 1000000000
.loop:                      ; do {
    mov   byte [rdi], al
    mov   byte [rdi+2], dl     ; store two bytes in the same dword
      ; no pointer increment, this is the same 32-bit dword every time
    dec   ecx
    jnz …
Run Code Online (Sandbox Code Playgroud)

performance x86 arm cpu-architecture cpu-cache

6
推荐指数
2
解决办法
263
查看次数