【问题标题】:Is there any padding for a struct of floats?浮动结构是否有任何填充?
【发布时间】:2019-06-20 03:17:33
【问题描述】:

我需要创建一块充满浮点数的内存。但我不想制作一个浮点向量,而是制作一个向量,其中每个成员都是一组相关的浮点数:

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 的在线编译器上)。花车都挤得很紧。但我担心该代码的可移植性。也许可以在某些架构上添加填充,从而打破内存的紧密性。

标准是否对这种情况作出任何保证?

【问题讨论】:

  • 为什么不直接使用数组呢?也可能相关stackoverflow.com/questions/5397447/struct-padding-in-c
  • @SamiKuhmonen 如果你的意思是我为什么不使用std::vector&lt;float&gt; 是因为我只需要作为一个整体访问每个 FloatStruct。每个索引都应该直接指向 FloatStruct,而向量和用户之间没有任何接口。同时我需要将整块紧张的内存发送到 GPU,所以我不能有任何漏洞。我知道我可以制作一个简单的自定义容器来实现相同的目标,但如果对上述代码有任何保证,我会抽出时间
  • 您可以考虑使用gsl::span&lt;float&gt; 之类的东西(正在标准化过程中)将您的阵列分组到子组中。你可以在这里找到一个实现:github.com/Microsoft/GSL
  • @2785528 但是,如果您创建一个结构数组,则如果它们包含填充,则由实现定义。因此浮动成员不能(可靠地)作为整个容器中的连续块来寻址。
  • 我一直在寻找副本。这并不是真正的重复,但我认为它解决了同样的问题:stackoverflow.com/questions/12138243/…

标签: c++ padding


【解决方案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

【讨论】:

    猜你喜欢
    • 2015-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-13
    • 2011-09-08
    • 2011-06-28
    • 2011-07-15
    相关资源
    最近更新 更多