代码之家  ›  专栏  ›  技术社区  ›  Stack Overflow is garbage

在C++中确定最大可能对齐方式

  •  20
  • Stack Overflow is garbage  · 技术社区  · 15 年前

    有吗 任何

    例如,在x86上,SSE指令需要16字节对齐,但据我所知,没有任何指令需要超过16字节对齐,因此任何类型都可以安全地存储到16字节对齐的缓冲区中。

    我需要创建一个缓冲区(比如char数组),在这里我可以写入任意类型的对象,因此我需要能够依赖于要对齐的缓冲区的开头。

    如果所有这些都失败了,我知道分配一个具有 new 保证具有最大对齐,但使用TR1/C++0x模板 alignment_of aligned_storage ,我想知道是否可以在buffer类中就地创建缓冲区,而不需要动态分配数组的额外指针间接寻址。

    我意识到有很多选项可以用来确定一组有界类型的最大对齐方式:并集,或者 校准

    6 回复  |  直到 13 年前
        1
  •  15
  •   Ricky65    11 年前

    在C++11中,头cstddef中定义的std::max_align_t是一种POD类型,其对齐要求至少与每个标量类型的对齐要求一样严格(一样大)。

    使用新的alignof操作符,它将非常简单 alignof(std::max_align_t)

        2
  •  11
  •   James McNellis    14 年前

    在C++0x中 Align 模板参数 std::aligned_storage<Len, Align>

    缺省对齐的值应该是任何大小不大于的C++对象类型的最严格的对齐要求。 Len .

    尚不清楚SSE类型是否会被视为“C++对象类型”

    默认参数不是TR1的一部分 aligned_storage ; 它是为C++0x添加的。

        3
  •  7
  •   Peter Mortensen icecrime    14 年前

    不幸的是,确保最大对齐比应该的要困难得多,而且AFAIK没有保证的解决方案。从 GotW 博客( Fast Pimpl article ):

    union max_align {
      short       dummy0;
      long        dummy1;
      double      dummy2;
      long double dummy3;
      void*       dummy4;
      /*...and pointers to functions, pointers to
           member functions, pointers to member data,
           pointers to classes, eye of newt, ...*/
    };
    
    union {
      max_align m;
      char x_[sizeofx];
    };
    

    便携式,但实际上很接近 足够了,因为很少或没有 无法在其上正常工作的系统

    这是我所知道的最接近的“黑客”了。

    我用它来 Pimpls 尤其然而,仅仅拥有分配器是不够的;为了让这样的分配器工作,我们必须假设类Foo的内存是在构造函数中分配的,同样的内存也只在析构函数中释放,而Foo本身是在堆栈上创建的。为了安全起见,我需要一个函数来查看类的“this”指针是否在本地堆栈上,以确定是否可以使用基于堆的超快速堆栈分配器。为此,我们必须研究特定于操作系统的解决方案:我使用 TIBs TEBs 对于Win32/Win64,我和我的同事找到了Linux和Mac OS X的解决方案。

    在研究了一周特定于操作系统的方法来检测堆栈范围、对齐要求,并进行了大量测试和分析之后,结果是一个分配器,它可以根据我们的滴答计数器基准在4个时钟周期内分配内存,而malloc/operator new的分配周期约为400个(我们的测试涉及线程争用,因此在单线程情况下,malloc可能会比这快一点,可能需要几百个周期)。我们添加了一个每线程堆堆栈,并检测到正在使用哪个线程,这将时间增加到了大约12个周期,尽管客户端可以跟踪线程分配器以获得4个周期的分配。这消除了映射中基于内存分配的热点。

    虽然您不必经历所有这些麻烦,但编写一个快速分配器可能比类似的东西更容易,也更普遍适用(例如:允许在运行时确定分配/取消分配的内存量) max_align 在这里 最大对齐 这很容易使用,但是如果您追求内存分配的速度(并且假设您已经分析了代码并在malloc/free/operator new/delete中找到了热点,并且您可以控制代码中的主要贡献者),那么编写自己的分配器确实可以起到作用。

        4
  •  5
  •   David Seiler    15 年前

    缺少一些 maximally_aligned_t 所有编译器都承诺忠实地支持任何地方的所有体系结构,我不知道如何在编译时解决这个问题。正如您所说,潜在类型集是无界的。额外的间接指针真的那么重要吗?

        5
  •  1
  •   Peter Mortensen icecrime    7 年前

    分配对齐内存比看起来要复杂-例如,请参阅 Implementation of aligned memory allocation

        6
  •  -2
  •   James Taylor    13 年前

    这就是我用的。除此之外,如果您正在分配内存,那么长度大于或等于max_alignment的新()d字符数组将与max_alignment对齐,这样您就可以使用该数组中的索引来获得对齐的地址。

    enum {
                max_alignment = boost::mpl::deref<
                    boost::mpl::max_element<
                            boost::mpl::vector<
                                boost::mpl::int_<boost::alignment_of<signed char>::value>::type,
                                boost::mpl::int_<boost::alignment_of<short int>::value>::type,
                                boost::mpl::int_<boost::alignment_of<int>::value>::type,                                boost::mpl::int_<boost::alignment_of<long int>::value>::type,
                                boost::mpl::int_<boost::alignment_of<float>::value>::type,
                                boost::mpl::int_<boost::alignment_of<double>::value>::type,
                                boost::mpl::int_<boost::alignment_of<long double>::value>::type,
                                boost::mpl::int_<boost::alignment_of<void*>::value>::type
                            >::type
                        >::type
                    >::type::value
                };
            }