与其他大小(2字节或1字节)相比,在处理器的自然字长(4字节或8字节)上运行的原子操作的性能如何?
如果我需要维护一个布尔原子变量,我正在试图找出最佳实践是什么:使用1字节优化空间,或者使用4/8字节优化性能。
发布于 2015-07-26 03:10:48
http://agner.org/optimize/提供了很多细节。
在x86上,由1字节数据组成的数组应该是好的.它可以用movzx (零扩展)加载,就像普通的mov一样快。
如果您想要将数据打包为8的另一个因子,x86就有一些操作来支持原子位字段。不过,我不知道编译器在为这种情况编写高效的代码方面会做得如何。即使是只写操作,对于保存要写入的位的字节,也需要一个缓慢的原子RMW循环。(在x86上,它将是一个lock OR指令,这是一个完整的内存屏障。在Intel Haswell上是8 uop,而字节存储是1 uop。(吞吐量为19倍。)如果这意味着大量的缓存丢失和很少的缓存丢失之间的区别,这可能仍然是值得的,尤其是。如果大部分访问是只读的。(阅读速度快,与非原子情况完全相同。)
在x86上,2字节(16位)的操作可能很慢,尤其是。在英特尔的CPU上。当英特尔指令解码器必须使用16位直接操作数来解码指令时,它们的速度会减慢很多。这是操作数大小前缀中的可怕的LCP摊档 .(8Bop有一个完全不同的操作码,32 vs.64位是由REX前缀选择的,它不会减慢解码器的速度)。所以16b是个奇数,你应该小心使用它。更愿意将16b内存加载到32b变量中,以避免部分寄存器惩罚和临时操作时的16位即时性。(AMD在处理movzx负载方面效率不高(需要一个ALU单元和额外的1个周期延迟),但是节省的内存几乎总是值得的(因为缓存的原因)。
32b是用于本地划痕变量的“最佳”大小。不需要前缀来选择该大小(增加代码密度),并且在使用低8b后再次使用完整寄存器时不会出现部分寄存器暂存或额外的uop。我相信这就是int_fast32_t类型的目的,但在x86 Linux上,这种类型不幸是64位。
https://stackoverflow.com/questions/29322218
复制相似问题