Nei*_*l G 18 c++ memory-alignment eigen c++11
阅读Eigen库文档,我注意到某些对象无法通过值传递.C++ 11或计划开发中是否有任何进展可以安全地按价值传递这些对象?
另外,为什么按值返回这些对象没有问题?
Nic*_*las 18
Eigen完全有可能只是一个写得非常糟糕的图书馆(或者只是考虑不周); 只是因为某些东西在线并不能使它成为现实.例如:
按值传递对象在C++中几乎总是一个非常糟糕的主意,因为这意味着无用的副本,而且应该通过引用传递它们.
一般而言,这不是一个好建议,具体取决于对象.有时需要预先C++ 11(因为您可能希望对象不可复制),但在C++ 11中,它永远不是必需的.您可能仍然会这样做,但始终无需通过引用传递值.如果它包含已分配的内存或其他内容,您可以按值移动它.显然,如果它是一种"看起来但不要触摸"的东西,那const&很好.
简单的结构对象,大概就像Eigen一样Vector2d,可能足够便宜(特别是在x86-64,其中指针是64位)复制在性能方面并不多.同时,它是开销(理论上),所以如果你在性能关键代码中,它可能会有所帮助.
然后,它可能不会.
Eigen似乎正在讨论的特殊崩溃问题与对象的对齐有关.但是,大多数C++ 03特定于编译器的对齐支持在所有情况下都保证了对齐.所以没有理由"让你的程序崩溃!".我从来没有见过一个基于SSE/AltaVec/etc的库,它使用了特定于编译器的对齐声明,这些声明会导致值参数崩溃.我已经使用了不少.
因此,如果他们遇到某种崩溃问题,那么我会认为Eigen具有......可疑的优点.不是没有进一步调查.
此外,如果一个对象通过值传递是不安全的,正如Eigen文档建议的那样,那么处理这个问题的正确方法就是使对象不可复制.复制分配没问题,因为它需要一个已经存在的对象.然而,Eigen没有这样做,这再次表明开发人员错过了API设计的一些细节.
但是,对于记录,C++ 11具有alignas关键字,这是声明对象应具有特定对齐的标准方式.
另外,为什么按值返回这些对象没有问题?
谁说没有(注意复制问题,而不是对齐问题)?不同之处在于您无法通过引用返回临时值.所以他们没有这样做,因为这是不可能的.
GMa*_*ckG 11
他们可以在C++ 11中做到这一点:
class alignas(16) Matrix4f
{
// ...
};
Run Code Online (Sandbox Code Playgroud)
现在,类将始终在16字节边界上对齐.
也许,也许我很傻,但这不应该是一个问题.鉴于这样的类:
class Matrix4f
{
public:
// ...
private:
// their data type (aligned however they decided in that library):
aligned_data_type data;
// or in C++11
alignas(16) float data[16];
};
Run Code Online (Sandbox Code Playgroud)
编译器现在有义务分配一个Matrix4f16字节的边界,因为这会破坏它; 班级alignas应该是多余的.但不知怎的,过去我一直都知道错了.