我需要创建一块紧密地用浮点数填充的内存。但是,我不想制作一个浮点数的向量,而是想创建一个向量,其中每个成员都是一组相关的浮点数:
struct FloatStruct
{
FloatStruct() :
a(1.f), b(10.f), c(100.f), d(1000.f), e(10000.f) { }
float a;
float b;
float c;
float d;
float e;
};
int main()
{
std::vector<FloatStruct> fvec(100);
auto pf = &fvec[0].a;
for(int i = 0; i < 500; ++i)
std::cout << *pf++ << "\n";
}
上面的代码显然可以在我使用MSVC的体系结构上(以及在某些使用GCC或Clang的在线编译器上)正常工作。花车都紧紧包装。但是我担心该代码的可移植性。也许可以在某些体系结构上添加填充,这样会破坏内存的紧密性。
标准是否对这种情况建立任何保证?
答案 0 :(得分:1)
要回答您的问题,是的,有些平台可能会引起麻烦。由于您特别提到它将要发送到GPU,因此对于某些体系结构而言可能会出现问题。我最近在macOS上遇到了Metal的问题,我想将数据减少25%,因此仅发送(x,y,z)而不是(x,y,z,1.0)作为我的纹理坐标,结果是坐标全掉了。 (我相信问题在于,GPU架构假定了CPU架构未提供的某种填充,尽管我认为如果相反的情况会产生类似的不良结果。)
跨平台兼容性的解决方案可能是定义一个宏,以确保所使用的每个编译器的填充正确。然后,在定义数据结构时,使用该宏获取正确的填充。所以看起来像这样:
#if MSVC
#define PACK_TIGHTLY <MSVC-specific definition of tight packing>
#define END_PACK_TIGHTLY <MSVC-specific definition of ending tight packing>
#elif Clang
#define PACK_TIGHTLY <clang-specific definition of tight packing>
#define END_PACK_TIGHTLY <clang-specific definition of ending tight packing>
#elif
// ... etc. for other platforms you want to support
#endif
然后,在定义struct
时,您将执行以下操作:
PACK_TIGHTLY
struct FloatStruct
{
FloatStruct() :
a(1.f), b(10.f), c(100.f), d(1000.f), e(10000.f) { }
float a;
float b;
float c;
float d;
float e;
};
END_PACK_TIGHTLY