gpt4 book ai didi

c++ - 对齐、总大小和 SSE

转载 作者:太空宇宙 更新时间:2023-11-04 11:43:15 24 4
gpt4 key购买 nike

我正在尝试 define a custom point type对于 PCL 库。在那篇教程中,他们讨论了内存对齐,所以我开始尝试了解它是如何工作的。

this page , 他们提出了一种计算结构总对齐度的相当简单的方法。比如这个结构

// Alignment requirements
// (typical 32 bit machine)

// char 1 byte
// short int 2 bytes
// int 4 bytes
// double 8 bytes

// structure C
typedef struct structc_tag
{
char c;
double d;
int s;
} structc_t;

大小为 24:

1 byte for the char + 7 bytes of padding + 8 bytes for the double + 4 bytes for the int + 4 bytes of padding

对于 g++ 4.8.1sizeof 返回 24。到目前为止,一切顺利。

现在,在 PCL 中,他们正在使用此方案定义点类型(这里是最简单的点,它在每个轴上保持位置)用于 SSE 对齐。

union
{
float data[4];
struct
{
float x;
float y;
float z;
};
};

sizeof 返回 16。使用 union 可以确保 point type 是 SSE 对齐的(我读到 here 是 16 字节对齐)并且结构轴值是可访问的。

引用自 PCL 文档:

The user can either access points[i].data[0] or points[i].x for accessing say, the x coordinate.

我的推理到此为止是否有效?


在我的例子中,我想将 float 更改为 double 值,以便在 XY 轴上获得更高的精度。

那么,将点类型声明为:

union {
float data[4];
struct {
double x;
double y;
float z;
};
};

?sizeof 返回 24,它不是 16 的倍数(所以我知道它不是 SSE 对齐的)但它是“双对齐”的。

我的问题是,我如何定义我的点类型才能将 XY 坐标存储为 double 坐标,并且仍然是 SSE 对齐?

PS:此外,如果你们中有人知道这方面的好资源,请告诉我。我想更好地理解这个主题。

PS 2:我忘了说,我正在尝试所有这些的平台是 64 位平台。

PS 3:如果可能的话,我对pre-C++11 解决方案很感兴趣。与 g++ 4.4(及其对应的 MinGW)一样古老的编译器必须能够构建新的点类型。

最佳答案

对象的大小和对齐不是一回事。如果结构的大小是 16 字节或一些倍数,这并不意味着它必须是 16 字节对齐的。

在你的情况下,因为你的代码是在 64 位模式下编译的,你只需要将结构填充到 32 字节。在 64 位模式下,堆栈在 Windows 和 Linux/Unix 中是 16 字节对齐的。

在 32 位模式下,它不必是 16 字节对齐的。你可以测试一下。如果您在 MSVC 中以 32 位模式运行下面的代码,您可能会看到数组的每个元素的地址不是 16 字节对齐的(您可能需要运行几次)。因此,即使结构的大小是 16 字节的倍数,它也不一定是 16 字节对齐的。

#include <stdio.h>

int main() {
union a {
float data[4];
struct {
double x;
double y;
float z;
float pad[3];
};
a b[10];
for(int i=0; i<10; i++) {
printf("%d\n", ((int)&b[i])%16);
}
}

如果您希望您的代码也能在 32 位模式下工作,那么您应该对齐内存。如果您在 Windows 或 Linux 上以 32 位模式运行下面的代码,您将看到它也始终是 16 字节对齐的。

#include <stdio.h>
#ifdef _MSC_VER // If Microsoft compiler
#define Alignd(X) __declspec(align(16)) X
#else // Gnu compiler, etc.
#define Alignd(X) X __attribute__((aligned(16)))
#endif

int main() {
union a {
float data[4];
struct {
double x;
double y;
float z;
float pad[3];
};
a Alignd(b[10]);
for(int i=0; i<10; i++) {
printf("%d\n", ((int)&b[i])%16);
}
}

关于c++ - 对齐、总大小和 SSE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20633325/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com