标签: memory-alignment

从字节数组加载 uint8x16_t 的对齐要求?

我们在调试构建下触发了一个断言来检查对齐情况。断言适用于加载到 using 中的字节uint8x16_t数组vld1q_u8。当断言触发时,我们没有观察到SIG_BUS.

下面是代码中的使用:

const byte* input = ...;
...

assert(IsAlignedOn(input, GetAlignmentOf(uint8x16_t));
uint64x2_t message = vreinterpretq_u64_u8(vld1q_u8(input));
Run Code Online (Sandbox Code Playgroud)

我还尝试了以下操作,并触发断言以进行对齐uint8_t*

assert(IsAlignedOn(input, GetAlignmentOf(uint8_t*));
uint64x2_t message = vreinterpretq_u64_u8(vld1q_u8(input));
Run Code Online (Sandbox Code Playgroud)

将字节数组加载到 with 时有哪些对齐uint8x16_t要求vld1q_u8


上面的代码中,input是一个函数参数。IsAlignedOn检查其两个参数的对齐方式,确保第一个参数至少与第二个参数对齐。GetAlignmentOf是检索类型或变量的对齐方式的抽象。

uint8x16_tuint64x2_t是 128 位 ARM NEON 向量数据类型,预计放置在 Q 寄存器中vld1q_u8是一个 NEON 伪指令,预计会被编译成VLD1.8指令。vreinterpretq_u64_u8是一条 NEON 伪指令,可简化数据类型的使用。

arm memory-alignment intrinsics neon

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

在 C++ 中声明、操作和访问未对齐的内存

我最近发布了一个关于未对齐内存访问的问题,但给出答案后,我有点迷失。我经常听到“对齐的内存访问比未对齐的访问效率要高得多”,但我实际上不确定什么是未对齐的内存。最后:

  • 什么是未对齐内存?
  • 如何在 C++ 中声明未对齐的内容?(小示例程序)
  • 如何在 C++ 中访问和操作未对齐的内容?(小示例程序)
  • 是否有一种方法可以使用定义的行为方法来操作未对齐的内存,或者所有这些都与 C++ 中的平台相关/未定义的行为有关?

c++ memory memory-alignment undefined-behavior

2
推荐指数
1
解决办法
1699
查看次数

在固定不同 CPU 的 2 个线程之间传递一些变量的最佳方式

我有一个问题需要了解是否有更好的解决方案。我编写了以下代码,将一些变量从编写器线程传递到读取器线程。这些线程固定到共享相同 L2 缓存的不同 CPU(禁用超线程)。

writer_thread.h

struct a_few_vars {
    uint32_t x1;
    uint32_t x2;

    uint64_t x3;
    uint64_t x4;
} __attribute__((aligned(64)));

volatile uint32_t head;
struct a_few_vars xxx[UINT16_MAX] __attribute__((aligned(64)));
Run Code Online (Sandbox Code Playgroud)

reader_thread.h

uint32_t tail;
struct a_few_vars *p_xxx;
Run Code Online (Sandbox Code Playgroud)

写入线程增加头变量,读取线程检查头变量和尾变量是否相等。如果它们不相等,则按如下方式读取新数据

while (true) {
    if (tail != head) {
        .. process xxx[head] ..
        .. update tail ..
    }
}
Run Code Online (Sandbox Code Playgroud)

性能是迄今为止最重要的问题。我使用的是 Intel Xeon 处理器,读取器线程每次都会从内存中获取 head 值和 xxx[head] 数据。我使用对齐数组来实现无锁

就我而言,是否有任何方法可以尽快将变量刷新到读取器CPU缓存中。我可以从写入器 CPU 触发读取器 CPU 的预取吗?如果存在的话,我可以使用 __asm__ 来使用特殊的英特尔指令。总之,在固定到不同 CPU 的线程之间传递结构中的变量的最快方法是什么?

提前致谢

c x86 intel memory-alignment cpu-cache

2
推荐指数
1
解决办法
246
查看次数

LD:链接描述文件中的对齐与子对齐

它们有何不同?

我读到 SUBALIGN() 以某种方式强制进行某种对齐。还有其他区别吗?

什么时候应该使用 ALIGN(),什么时候应该使用 SUBALIGN()?

linker gcc ld memory-alignment sections

2
推荐指数
1
解决办法
2826
查看次数

为什么#pragma pack 也会影响结构体自身的对齐方式?

我注意到,当在结构体周围使用 #pragma pack 时,它内部的对齐方式并不是唯一受到影响的对齐方式,而且结构体本身的对齐方式也会发生变化。考虑以下:

#include <stdio.h>
#include <stdint.h>

#pragma pack(1)
typedef struct _TEST
{
    uint32_t a;
} TEST;
#pragma pack()

volatile uint8_t n;
TEST b;

int main()
{

    printf("Address %lX rem %lu\n", (long unsigned int)&b, (long unsigned int)(&b)%(sizeof(int)));  
    return 0;
}

Run Code Online (Sandbox Code Playgroud)

您可以在这里尝试此代码: https: //onlinegdb.com/BkebdxZEU

程序返回Address 601041 rem 1,这意味着该编译指示也对结构体产生了aligned(1) 的效果。

这是为什么?这是一个定义的行为吗?

c memory-alignment pragma-pack

2
推荐指数
1
解决办法
637
查看次数

当外部基础类型未按要求对齐时的atomic_ref

我在p0019r8上读到以下内容:

atomic_ref(T& obj);
Run Code Online (Sandbox Code Playgroud)

要求:引用的对象应与 对齐required_alignment

当未对齐时, cppreference将其解释为 UB:

如果 obj 未与 required_alignment 对齐,则行为未定义。


那么您期望实现如何处理它呢?

并且实现可以检查编译时 alignof,但实际上类型可能比对齐更对齐alignof。实现可以解释指针位并检查运行时对齐,但这是额外的运行时检查。

最终我看到以下选项:

  • 什么都不做 - 以令人不快的方式实现运行时未定义的行为,仅支持正确的使用
  • 检查编译时对齐 ( alignof) 并在错误时发出警告
  • 检查编译时对齐 ( alignof) ,如果错误不正确,则编译时失败,因为实际对齐可能大于静态类型可见的对齐
  • 检查编译时对齐 ( alignof),如果错误不正确,则在运行时失败,因为实际对齐可能大于静态类型可见的对齐
  • 检查编译时对齐 ( alignof) 并在错误时回退到基于锁
  • 检查运行时对齐(指针位),如果错误则在运行时失败
  • 检查运行时对齐(指针位),如果错误则回退到基于锁

c++ memory-alignment undefined-behavior stdatomic c++20

2
推荐指数
1
解决办法
332
查看次数

即使不需要,编译器也会应用结构填充

我试图了解结构填充在 C 中的工作原理。特别是在 Linux x86-64 环境中。为此,我重新排列了给定结构的成员的顺序,以查看在不需要时是否不会应用填充。然而,当我编译并运行打印每个结构的大小的代码时,填充被应用于它们两个,即使第二个结构(struct b)的成员以这样的方式排列,连续地将它们存储在内存中不会导致其中之一占据多个字块。

#include <stdio.h>

struct a {
    int ak; 
    char ac; 
    char* aptr; 
};

struct b {
    char* bptr;
    int bk;
    char bc;
};



int main(int argc, char* argv[]) {
    printf("%lu\n", sizeof(struct a));
    printf("%lu\n", sizeof(struct b));
}

Run Code Online (Sandbox Code Playgroud)

输出:

16

16
Run Code Online (Sandbox Code Playgroud)

c struct padding cpu-architecture memory-alignment

2
推荐指数
1
解决办法
104
查看次数

编译器是否始终将结构放置在对齐的地址处?

假设我有结构:

typedef struct my_char {
    char c;
} my_char_t;
Run Code Online (Sandbox Code Playgroud)

我可以假设任何时候内存地址都会对齐吗?

我想也许是的,因为在教程中我看到了这样的结构:

typedef struct my_char2 {
    char c;
    int i;
} my_char2_t;
Run Code Online (Sandbox Code Playgroud)

c和之间有填充i,因此看起来假设c是对齐的。

c struct memory-alignment

2
推荐指数
1
解决办法
128
查看次数

即使正在访问的成员充分对齐,访问未对齐联合的成员是否是未定义的行为?

在 C 中,如果我尝试通过未对齐的指针访问类型,则可能会发生不好的事情:

int x[2]; // Assuming CHAR_BIT == 8 && sizeof(int) == 4
*(int *)((char *)x+1) = 10; /* Undefined behavior due to unaligned pointer dereference
    even though there are no out of bounds accesses */
Run Code Online (Sandbox Code Playgroud)

但是,如果相关类型是 a但我只访问不具有对齐要求union的成员,该怎么办?union

union X {
    int i;
    char c[4];
} x[2];
((union X *)((char *)x+1))->i = 10; /* I am guessing this is still undefined behavior
    because accessing an unaligned int through a union does not make a difference as …
Run Code Online (Sandbox Code Playgroud)

c memory-alignment undefined-behavior unions language-lawyer

2
推荐指数
1
解决办法
94
查看次数

为了获得尽可能快的速度,我应该对 CUDA 中的矩阵使用什么步幅?

我正在处理大小范围从 2,000x2,000 到 5,000x5,000 的矩阵,执行乘法和 QR 分解等运算。例如,我很好奇是否应该将所有矩阵的步长对齐 64,以获得最佳性能。另外,由于缓存关联性,我是否应该避免步幅为某些页面大小的倍数,或者这不适用于 GPU 内存?

cuda memory-alignment stride

2
推荐指数
1
解决办法
72
查看次数