标签: memory-alignment

为什么 gcc 不能将结构体的对齐方式减少到小于其单个字段之一的对齐方式

我有一个employee实例化的结构定义monica。结构看起来像这样

struct __attribute__((aligned(2))) employee {
    int salary; // 4 bytes
    int age; // 4 bytes
} monica;
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我强制将结构对齐,2但 gcc 不会将结构对齐设置为 2,也不会引发错误。我尝试使用alignof宏(include <stdalign.h>)打印结构的对齐方式,该宏4作为结构的对齐方式返回。为什么 gcc 不能将结构的对齐方式设置为小于其字段之一的最大对齐方式的值。

我尝试通过另外添加一个指针作为结构中的字段来重现该问题。在将指针添加为字段时,我注意到 gcc 不允许我使用__attribute__((aligned(x))).

1GCC 允许我通过使用设置结构的对齐方式__attribute__((packed)),但它仍然不允许我1通过使用设置对齐方式__attribute__((aligned(1)))。为什么会发生这种情况?

海湾合作委员会 x86 v7.1.1

c memory struct memory-alignment

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

为什么大小小于 CPU 字大小的数据需要以其大小的倍数对齐?

我们假设有一个 32 位 CPU 和 2 字节short。我知道 4 字节int需要在 4 的倍数地址处对齐,以避免额外读取。

问题:

  1. 如果 处存储了短路,CPU 仍可以在一次操作中0x1读取。0x0那么,为什么 Shorts 需要以 2 的倍数地址对齐呢?
  2. 如果一个short存储在0x2,为什么它会被认为是对齐和高效的,因为CPU只能从0x0读取并丢弃前两个字节?

有一个问题与此非常相似,但是,答案仅告诉我们short结构体和独立变量中的对齐要求是相同的。还有一条获得 2 票赞成的评论说:

在许多机器上,当数量是 N 字节对齐时,访问 N 字节数量(至少是 {1, 2, 4, 8, 16} 中的 N)的效率最高。生活就是这样;习惯它,因为我怀疑芯片制造商会仅仅因为你认为它不应该是这样而改变它。

但为什么?

c memory cpu-architecture memory-alignment

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

为什么结构体的对齐不等于它的大小?

我读过一些有关内存对齐的问题,但没有找到与我的问题相关的任何答案。

这里我有2个问题:

struct MyData
{
    short Data1;
    short Data2;
    short Data3;
};
Run Code Online (Sandbox Code Playgroud)
  1. 为什么对齐方式是MyData等于2而不是6 == sizeof(MyData)?是否有任何特定原因导致struct使用与其他基元类型不同的方法来计算对齐方式?

  2. 根据微软的Alignment文档:

    如果地址的对齐方式为 Xn+0,则称该地址与 X 对齐

    这是否意味着只有当对象的MyData地址是其对齐方式的倍数时才对齐(2在本例中就是这样)?如果是这样,那么我们可以在内存中分配的对齐对象越大struct,对齐的对象就越少吗?MyData我的假设正确吗?

c c++ memory struct memory-alignment

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

SSE2 - 16字节对齐的动态内存分配

编辑:

这是SSE2编译器错误的后续内容

这是我之前遇到的真正的错误,并通过更改Michael Burr建议的_mm_malloc声明在下面转载:

SO.exe中0x00415116处的未处理异常:0xC0000005:访问冲突读取位置0xffffffff.

在线 label: movdqa xmm0, xmmword ptr [t1+eax]

我正在尝试动态分配t1,t2并且根据本教程,我使用过_mm_malloc:

#include <emmintrin.h>
int main(int argc, char* argv[])
{ 
 int *t1, *t2;
 const int n = 100000;
 t1 = (int*)_mm_malloc(n*sizeof(int),16);
 t2 = (int*)_mm_malloc(n*sizeof(int),16);
 __m128i mul1, mul2;
  for (int j = 0; j < n; j++)
  {
  t1[j] = j;
  t2[j] = (j+1);
  } // set temporary variables to random values
  _asm
  { …
Run Code Online (Sandbox Code Playgroud)

c++ assembly memory-alignment sse2 visual-c++-2005

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

处理多重继承时如何对齐指针?

假设我们有一个具体的类A和一个抽象类B.

考虑一个具体的C,它继承自A和B,并实现B:

class C : public A, public B  
{  
/* implementation of B and specific stuff that belongs to C */  
};
Run Code Online (Sandbox Code Playgroud)

现在我定义一个签名是什么的函数 void foo(B* b);

这是我的代码,我可以假设每个指向B的指针都是A和B.在foo的定义中,如何获得指向A的指针?一个讨厌但有效的技巧是将指针对齐,如下所示:

void foo(B* b)  
{  
    A* a = reinterpret_cast<A*>(reinterpret_cast<char*>(b) - sizeof(A));
    // now I can use all the stuff from A  
}
Run Code Online (Sandbox Code Playgroud)

请记住,C没有超类型,实际上,有许多类似于C的类,只有A和B.可以自由地质疑我的逻辑和这个设计样本,但问题只是关于指针对齐.

c++ pointers multiple-inheritance memory-alignment vtable

0
推荐指数
1
解决办法
288
查看次数

为什么大于128的对齐行为很奇怪?

所以我一直在忙着编写自己的自定义内存分配器,但是我遇到了一些我不理解的奇怪行为.

考虑以下代码:

void* PointerUtil::AlignForward(void* address, const uint8_t& alignment)
{
    return (void*)(((uintptr_t)(address) + (uintptr_t)(alignment - 1)) & (uintptr_t)(~(alignment - 1)));
}
Run Code Online (Sandbox Code Playgroud)

这应该采用指针和对齐要求,并修改指针使其在正向(正向)上正确对齐.

但是,当我这样测试时:

int address = 1240;

std::cout << (uintptr_t)memory::PointerUtil::AlignForward((void*)((uintptr_t)address), 512) << std::endl;
std::cout << (uintptr_t)memory::PointerUtil::AlignForward((void*)((uintptr_t)address), 256) << std::endl;
std::cout << (uintptr_t)memory::PointerUtil::AlignForward((void*)((uintptr_t)address), 128) << std::endl;
std::cout << (uintptr_t)memory::PointerUtil::AlignForward((void*)((uintptr_t)address), 64) << std::endl;
std::cout << (uintptr_t)memory::PointerUtil::AlignForward((void*)((uintptr_t)address), 32) << std::endl;
Run Code Online (Sandbox Code Playgroud)

我得到的输出是这样的:

0
0
1280
1280
1248
Run Code Online (Sandbox Code Playgroud)

这似乎不对.它应该是:

1536
1280
1280
1280
1248
Run Code Online (Sandbox Code Playgroud)

这里出了什么问题?

c++ memory pointers memory-alignment

0
推荐指数
1
解决办法
57
查看次数

普通旧数据和`std :: memcpy`对齐问题

试图回答另一个问题,我提出了一个解决方案,用于std::memcpy()将通用类型存储在chars 的缓冲区中.

我怀疑存储POD可能存在内存对齐问题(我知道有非POD类型,因为std::string非常非常危险).

简而言之:以下程序存在内存对齐问题?

如果它们是,那么可以写一些类似的东西(将POD值存储在char缓冲区中)是安全的吗?如何?

#include <cstring>
#include <iostream>

int main()
 {
   char  buffer[100];

   double  d1 { 1.2 };

   std::memmove( buffer + 1, & d1, sizeof(double) );

   double  d2;

   std::memmove( & d2, buffer + 1, sizeof(double) );

   std::cout << d2 << std::endl;

   return 0;
 }
Run Code Online (Sandbox Code Playgroud)

c++ memory-alignment memcpy

0
推荐指数
1
解决办法
405
查看次数

C++中未初始化的内存

operator new在 C++ 中,分配和初始化内存(通过调用默认构造函数)。如果我想要内存未初始化怎么办?在这种情况下如何分配内存?

malloc例如,在 CI 中可以使用它只会分配内存,而不是初始化它。

c++ memory memory-management memory-alignment

0
推荐指数
1
解决办法
1891
查看次数

编译器会秘密增加struct的对齐吗?

我有一个8字节对齐的结构,但是当我连续定义这种类型的某些变量但不在数组中时,它似乎是16字节对齐.我的问题是,编译器是否为某种目的增加了它的对齐?

我的测试代码是:

#include <stdio.h>
#include <stdint.h>
struct a{
    long l[3];
};

struct a a1;
struct a a2;
struct a a3;

int main(){
    printf("%lx\n", (uintptr_t)&a1);
    printf("%lx\n", (uintptr_t)&a2);
    printf("%lx\n", (uintptr_t)&a3);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是:

601030
601050
601070
Run Code Online (Sandbox Code Playgroud)

c c++ struct memory-alignment

0
推荐指数
1
解决办法
93
查看次数

是不是__m128d本地对齐?

我有这个代码:

double a[bufferSize];
double b[voiceSize][bufferSize];
double c[voiceSize][bufferSize];

...

inline void AddIntrinsics(int voiceIndex, int blockSize) {
    // assuming blockSize / 2 == 0 and voiceIndex is within the range
    int iters = blockSize / 2;
    __m128d *pA = (__m128d*)a;
    __m128d *pB = (__m128d*)b[voiceIndex];
    double *pC = c[voiceIndex];

    for (int i = 0; i < iters; i++, pA++, pB++, pC += 2) {
        _mm_store_pd(pC, _mm_add_pd(*pA, *pB));
    }   
}
Run Code Online (Sandbox Code Playgroud)

但是,"有时",它提高访问内存冲突,我认为它是由于缺少我的3个数组的内存对齐的a,bc.

但是,由于我操作__m128d(使用__declspec(align(16))),当我转换为指针时,是否保证对齐? …

c++ sse simd memory-alignment intrinsics

0
推荐指数
1
解决办法
109
查看次数