C 无锁算法的指针对齐

C 无锁算法的指针对齐,c,linux,x86-64,lock-free,C,Linux,X86 64,Lock Free,当使用calloc时,指向新分配内存的指针至少与一定数量的最低有效位对齐,这意味着最低有效位(作为标记的指针)可用于无锁算法,实际上通常用于这些算法。我在linux ubuntu服务器(x86_64 GNU/linux,3.10.23-xxxx-std-ipv6-64-vps)上测试内存菜单功能,从我的实验来看,似乎4个最低有效位被设置为0。从我所读到的内容来看,指针对齐方式是将表示为uintptr的指针除以4(对齐到2个最低有效位) 从POSIX(linux)中的内存菜单系统获得的新分配内存指

当使用calloc时,指向新分配内存的指针至少与一定数量的最低有效位对齐,这意味着最低有效位(作为标记的指针)可用于无锁算法,实际上通常用于这些算法。我在linux ubuntu服务器(x86_64 GNU/linux,3.10.23-xxxx-std-ipv6-64-vps)上测试内存菜单功能,从我的实验来看,似乎4个最低有效位被设置为0。从我所读到的内容来看,指针对齐方式是将表示为uintptr的指针除以4(对齐到2个最低有效位)

从POSIX(linux)中的内存菜单系统获得的新分配内存指针中,在初始内存分配过程中始终设置为0的最低有效位的最小数目是多少

linux系统上可用作标记指针(如无锁算法)的最低有效位的最大数量是多少

如何强制编译器将新分配的指针和最低有效位的exect数对齐


指针的对齐是否会影响系统的整体性能,以及如何影响?

我恐怕无法回答您的整个问题,但我可以从以下方面开始:

指针对齐可能不仅会改变性能,而且是使代码正常工作所必需的。特别是对于ARM处理器之类的东西,如果指针未对齐,则无法读取大于1字节的数字。这样做将导致错误


例如,如果我使用大数据流,我更喜欢将数据对齐,以便可以同时读取更多字节,而不是逐字节读取,这将花费更多的时间/CPU

x86/x86_64上体系结构读/写未对齐的内存需要付出性能成本,因为您将需要两个内存操作,而不是一个:与内存之间的总线操作总是对齐的。 在GNU/Linux上,您可以使用posix_memalign&C在用户空间中获得堆对齐内存(man memalign)

例如,有些编译器还支持宏来获得堆栈上的对齐内存

/* GCC align declarator */
#define MYMEMALIGN(x, y) x __attribute__( (aligned( y )) )
#endif

但我猜这是不可移植的解决方案。

由于许多相关原因,对齐在优化中很重要:

  • 缓存线的有效使用
  • 避免禁用预取逻辑
  • 矢量寄存器/指令的最佳使用(SSE、AVX)
  • 特别是在涉及I/O时,内存页对齐也很重要
您可以在此处找到有关英特尔体系结构的非常好的参考资料:

快速回答您的问题:

新数据中最低有效位的最小数目是多少 分配的内存指针,从中的内存菜单系统获取 POSIX(linux),在初始内存期间始终设置为0 分配过程

这实际上取决于您所说的CPU/体系结构

可以使用的最低有效位的最大数量是多少 在linux系统上用作标记指针(例如,无锁算法)

与前者相同:您应该使用<代码> STD::原子或Boo::原子< /代码>,以便具有某种可移植性,如果C++是选项。

在英特尔体系结构上,如果数据正确对齐,32位、x86_32和x86_64的内存加载和存储是原子的


如果您真的喜欢这种低级别,请不要忘记查看内存语义、内存围栏等(“上述手册中的围栏说明”)

没有设置为0的最低有效位的“最小”或“最大”数。内存对齐高度依赖于平台。您所知道的是,系统通常有一种限制内存对齐的类型,
malloc()
和其他内存分配函数总是返回一个指针,该指针适合最严格的类型(因此可以与任何类型一起使用)为什么你认为内存对齐和无锁算法之间有关系?我想你可能想阅读。通常,内存对齐基于sizeof(double)。如果调用手册页中的函数,则可以更改。@Robert Jacobs内存对齐和无锁算法之间的关系是在能够使用标记指针的情况下。要补充@Sigismondo的优秀答案,请注意:如果内存未对齐,某些SSE/AVX指令会生成总线错误。在最近的英特尔CPU上,未对齐加载/存储的惩罚为零,除非数据穿过缓存线。而且可能会因为跨页线而受到更大的惩罚。因此,尝试对齐数据仍然是一个好主意,但是对于需要在数据中使用不同偏移量的情况,对于未对齐的数据有很好的硬件支持。