标签: memory-alignment

使用数组下标运算符访问struct成员

设T型和只具有T型均匀元素的结构.

struct Foo {
    T one,
    T two,
    T three
};
Run Code Online (Sandbox Code Playgroud)

我想以下面的方式访问它们:

struct Foo {
    T one,
    T two,
    T three

    T &operator [] (int i)
    {
        return *(T*)((size_t)this + i * cpp_offsetof(Foo, two));
    }
};
Run Code Online (Sandbox Code Playgroud)

其中cpp_offsetof宏(它被认为是正确的)是:

#define cpp_offsetof(s, m)   (((size_t)&reinterpret_cast<const volatile char&>((((s*)(char*)8)->m))) - 8)
Run Code Online (Sandbox Code Playgroud)

C++标准并不能保证它,但是我们可以假设成员与固定偏移相距甚远,并且上面是正确的跨平台解决方案吗?


100%兼容的解决方案是:

struct Foo {
    T one,
    T two,
    T three

    T &operator [] (int i) {
        const size_t offsets[] = { cpp_offsetof(Foo, one), cpp_offsetof(Foo, two), cpp_offsetof(Foo, three) };
        return *(T*)((size_t)this + offsets[i]); …
Run Code Online (Sandbox Code Playgroud)

c++ cross-platform memory-alignment

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

为什么不消除关于这个结构填充字节的需要?

考虑以下简单结构:

struct Struct {
public:
  char  a;
  short int b;
  char  c;
};
Run Code Online (Sandbox Code Playgroud)

如果此结构的实例放置在偶数(16位对齐)地址,则需要两个填充字节来修复对齐(对于b数组中的任何后续实例都是如此).

但是,实例可以放在奇数地址,然后即使没有填充字节,对齐仍然是正确的.

所以我做了一个测试并观察到Visual C++ 2010将添加这两个填充字节,这表明它总是将它们放在偶数地址.

为什么VC++不会将它们放在奇数地址上,每个对象节省2个字节?有什么我不知道的吗?

c++ padding visual-studio-2010 memory-alignment visual-c++

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

pragma打包一个stl容器

当我宣布这样的结构时:

#pragma pack(1)
structure MyStruct{
    uint32_t first;
    uint8_t second;
};
#pragma pack()
Run Code Online (Sandbox Code Playgroud)

我显然希望它占用5个字节的内存.那么这样的矢量将如何表现:

std::vector<MyStruct> MyVec;
Run Code Online (Sandbox Code Playgroud)

或者这样的地图:

std::map<MyStruct> MyMap;
Run Code Online (Sandbox Code Playgroud)

他们会遵守要求的协调吗?我可以强制STL结构吗?

c++ stl memory-alignment

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

结构成员的运行时对齐

考虑以下struct:

struct SomeStruct
{
    int a;
    float b;
    double c;
};
Run Code Online (Sandbox Code Playgroud)

据我所知,当声明一个类型的对象时SomeStruct,struct(在这种情况下a)的第一个成员的地址等于对象本身的地址.

SomeStruct obj;
assert(reinterpret_cast<uintptr_t>(&obj) == reinterpret_cast<uintptr_t>(&obj.a));
Run Code Online (Sandbox Code Playgroud)

我可以假设a成员的运行时地址是否符合对齐要求,SomeStruct即使alignof(int) != alignof(SomeStruct)

c++ memory-alignment c++11

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

CUDA结构对齐正在减慢我的代码(可编译示例)

我有一个模拟计算在电场和磁场中移动的带电粒子的3D矢量. 我尝试使用说明__align__符在CUDA中加速这一点,认为可能限制因素是全局内存读取和写入,但使用__align__最终减慢它(可能是因为它增加了总内存需求).我也试过使用float3,float4但他们的表现相似

我已经创建了此代码的简化版本并将其粘贴在下面以显示我的问题. 下面的代码应该是可编译并通过改变的定义CASE在第四行至0,12,可以尝试我上述不同的选项. 两个函数,ParticleMoverCPU并且ParticleMoverGPU被定义为比较CPU VS GPU性能.

  1. 有没有理由我的内存合并尝试减慢而不是加速我的代码?
  2. 有没有其他任何立即显而易见的事实,我没有做到这一点,我可以做到比一个"令人尴尬的并行"代码这样的60倍加速更好?

谢谢!

CPU - Intel Xeon E5620 @ 2.40GHz

GPU - NVIDIA Tesla C2070

// CASE 0: Regular struct with 3 floats
// CASE 1: Aligned struct using __align__(16) with 3 floats
// CASE 2: float3
#define CASE        0   // define to either 0, 1 or 2 as described …
Run Code Online (Sandbox Code Playgroud)

cuda memory-alignment

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

为什么具有虚函数的类与没有的类对齐?

理查德鲍威尔的这次cppcon谈话的启发,我创建了以下代码片段来愚弄:

#include <iostream>
using std::cout;
using std::endl;

struct erdos
{
  void who()
  {
    cout << "erdos" << endl;
  }
  float f1;
  float f2;
};

struct fermat : public erdos
{
  float f3;
};

struct fermat2 : public fermat
{
  float f4;
};

struct fermat3 : public fermat2
{
  float f5;
};

int main(void)
{
  erdos e;
  cout << "sizeof(e)" << sizeof(e) << endl;
  fermat f;
  cout << "sizeof(f)" << sizeof(f) << endl;
  fermat2 f2;
  cout << …
Run Code Online (Sandbox Code Playgroud)

c++ virtual-functions memory-alignment memory-layout vptr

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

C++中的结构大小(sizeof)与数组的实际大小不一致

我使用以下结构的动态数组:

struct TestStructure
{
    unsigned int serial;
    int channel;
    int pedestal;
    int noise;
    int test;
};
Run Code Online (Sandbox Code Playgroud)

所述的sizeof(TestStructure)返回20,所以我假定有在结构上没有填充/比对.这在逻辑上是因为只有4字节类型.

但我发现结构的大小乘以元素数不等于数组的大小.阵列的元素之间还有一个额外的填充!因此,在以下代码中:

TestStructure* test_struct = new TestStructure[element_count];
for (int i = 0; i < element_count; i++)
  FillStructure(test_struct, i, i, i, i, i, i); // assigning 'i' for all elements

Long_t size_value = element_count * sizeof(TestStructure);
unsigned char* p_value = new unsigned char[size_value];
memcpy(p_value, test_struct, size_value);
Run Code Online (Sandbox Code Playgroud)

字符的输出数组包含元素之间的附加填充:

sizeof(TestStructure) = 20. element_count = 10. size_value = 200. char array in the hex format:
0 …
Run Code Online (Sandbox Code Playgroud)

c++ arrays struct sizeof memory-alignment

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

从未对齐的uint8_t重读为uint32_t数组-未获取所有值

我正在尝试将uint8_t数组强制转换为uint32_t数组。但是,当我尝试执行此操作时,我似乎无法访问每个连续的4个字节。

让我们说我有一个8字节的uint8_t数组。我想作为一个uint32_t访问字节2-> 6。

这些都得到相同的值*((uint32_t*)&uint8Array[0])*((uint32_t*)&uint8Array[1])*((uint32_t*)&uint8Array[2])*((uint32_t*)&uint8Array[3])

虽然*((uint32_t*)&uint8Array[4])按预期方式获得字节4-> 8。

看来我无法从任何地址访问4个连续字节?

有什么办法可以做到这一点?

cuda alignment memory-alignment

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

包含特征向量的类的奇怪大小

包含两个特征向量的C++类具有奇怪的大小.我的问题MWE在这里:

#include <iostream>
#include "Eigen/Core"

class test0 {
  Eigen::Matrix<double,4,1> R;
  Eigen::Matrix<double,4,1> T;
};

class test1 {
  Eigen::Matrix<double,4,1> R;
  Eigen::Matrix<double,3,1> T;
};

class test2 {
  Eigen::Matrix<double,4,1> R;
  Eigen::Matrix<double,2,1> T;
};

class test3 {
  Eigen::Matrix<double,7,1> T;
};

class test4 {
  Eigen::Matrix<double,3,1> T;
};

int main(int argc, char *argv[])
{
    std::cout << sizeof(test0) << ", " << sizeof(test1) << ", " << sizeof(test2) << ", " << sizeof(test3) << ", " << sizeof(test4) << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我在我的系统上得到的输出(MacBook Pro,Xcode Clang ++编译器)是:

64,64,48,56,24 …

c++ sizeof padding memory-alignment eigen

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

机器的最小对齐要求

我正在读一本关于编译器设计和实现的书.在关于存储管理的部分中,作者编写了一个分配内存的函数.他希望函数适合任何类型.他声称下面的联合大小是主机上的最小对齐.我不太明白这意味着什么.从书中可以看出:"......它的领域最有可能具有最严格的对齐要求."

union align {
    long l;
    char *p;
    double d;
    int (*f) (void);
};
Run Code Online (Sandbox Code Playgroud)

有人可以解释什么是"最严格的对齐要求"意味着什么?它如何在主机上实现最小的对齐?

c memory-alignment

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