是否可以内联一个重载的运算符? [英] Is it possible to inline an overloaded operator?

查看:93
本文介绍了是否可以内联一个重载的运算符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经剖析了我的应用程序,看看为什么我的3D矢量实现几乎比相应的C函数调用快3倍:结果证明每个函数调用比实际执行的算法花费更多的时间!我已经将函数调用次数减少到3次,但这并没有多大帮助。



似乎由于某种原因,算术操作员调用比其他函数调用花费的时间更多,并且,在查看反汇编时,我发现了原因:尽管完全优化,它们是唯一没有内联的函数!每个调用需要大约10个准备命令,仅用于存储两个操作数。与此相比,调用相应的C函数只需要2个命令来存储每个双指针参数。



这里是我的代码的简化部分(添加包括守卫作为需要):

I''ve profiled my application to see why my 3D-vector implementation is almost 3 times slower than the corresponding C function calls: the results proved that every single function call costs more time than the actual arithmetic being performed! I''ve already cut the number of function calls down to 3, but that doesn''t help a lot.

It seems that for some reason, the arithmetic operator calls take even more time than other function calls, and, looking at the disassembly, I''ve found out why: they are the only functions that haven''t been inlined in spite of full optimization! Each call takes ~10 commands of preparation, just for storing the two operands. compared to that, calling the corresponding C function only takes 2 commands to store each double pointer argument.

here''s a simplified segment of my code (add include guards as needed):

// header vector3d.h
class VectorExpression3d;
class Vector3d {
public: // will see about visibility later...
   double x, y, z;
   Vector3d(const VectorExpression& ve);
   Vector3d& operator=(const vectorExpression3d& ve);
};
#include "vectorexpression3d.h"
// implementation ...

// header vectorexpression3d.h
#include "vector3d.h"
class VectorExpression3d {
public:
   double x, y, z, scale;
   VectorExpression3d(const Vector3d& v1, const Vector3d& v2)
     : x(v1.x+v2.x), y(v1.y+v2.y), z(v1.z+v2.z), scale(1.0) {}
};

// main cpp file
#include "vector3d.h"
inline VectorExpression3d operator+(const Vector3d& v1, const Vector3d& v2) {
   return VectorExpression3d(v1, v2);
}

int main() {
  // ...
  Vector3d v1, v2, v3;
  v3 = v1+v2; // invokes non-inlined call to operator+ above, 
              // then inlined(!) VectorExpression3d constructor
              // then inlined(!) Vector3d constructor
              // then inlined VectorExpression3d destructor
  // ...
}





我正在使用VS 2010,似乎编译器忽略了对任何运算符的内联语句。我知道我不能强迫内联 - 但它应该是可能的,因为操作员是微不足道的,它甚至应该是容易的!那么问题是什么?为什么VS 2010不会内联我的运营商?毕竟不可能吗?



根据我的分析结果,对operator +的调用本身占用了添加语句总时间的一半以上,包括任务和建设/破坏一个临时的!



PS:

也许这很重要,但我忘了提到实际课程实际上是模板(目前只有模板arg是基本类型(double),所以不是一个大问题)



I''m using VS 2010, and it seems the compiler ignores inline statements to any of the operators. I know that I cannot force inlining - but it should be possible, and since the operators are trivial, it should even be easy! So what is the problem? Why doesn''t VS 2010 inline my operators? Is it not possible after all?

According to my profiling results, the call to operator+ by itself uses up more than half of the total time of the addition statement, including the assignment and construction/Destruction of a temporary!

P.S.:
Maybe this is important, but I forgot to mention that the actual classes are, in fact, templates (only template arg is the base type (double) so far, so not a biggie)

推荐答案

尝试将运算符+实现移动到标题文件。 VS不喜欢从.cpp文件中插入内容(这可能会导致链接问题,所以要小心)。您也可以尝试 __ forceinline 而不是内联但它可能没有任何区别,这仍然取决于编译器。



如果这些都无效,你可以在 VectorExpression3d 上使用专家构造函数,它需要两个实例并生成第3个。它可能很笨拙而且不像数学,但它可以解决内联问题。内联构造函数是非常基本的优化策略。
Try moving your operator+ implementation to the header file. VS doesn''t like inlining things from .cpp files ( this might cause linkage issues down the line so be careful ) . You could also try __forceinline instead of inline but it may not make any difference, that''s still up to the compiler.

If none of this works could you use a specialist constructor on VectorExpression3d which takes two instances and produces a 3rd. It may be awkward and a bit less math-like but it may solve the inlining issue. Inlining constructors is pretty much basic optimization strategy.


顺便说一下,你通常应该在operator + =的术语中定义operator +,因为它可以提高效率,而另一个可以非常简单根据已定义的运算符实现+ =。



By the way, you should generally define operator + in term of operator += as that one can be made more efficient and the other can be trivially be implemented in term of already defined operator +=.

class Vector3d
{
public:
  Vector3d& operator+=(const Vector3d &other)
  {
    x += other.x;
    y += other.y;
    z += other.z;
  }
};

// Notice that + operator is not a member function and does not need to be friend
inline Vector3d operator+(const Vector3d &lhs, const Vector3d &rhs)
{
  return Vector3d(lhs) += rhs;
}





http://courses.cms.caltech.edu/cs11/material/cpp/donnie/cpp-ops.html [ ^ ]

http://stackoverflow.com/questions/4421706/operator-overloading [ ^ ]


对,我终于在原始资源中发现了问题码。实际上有两个问题:



1.我需要将operator +的定义移动到一个标题(为所有运算符定义创建一个单独的标题)。感谢Matthew Faithfull指出这一点。



2.我的 VectorExpression3d 类的原始版本是由一个UML工具,它自动添加了一个(空)析构函数。删除该析构函数后,编译器终于可以内联我的运算符+ 了!我不太确定,但我怀疑析构函数阻止编译器将类视为POD类型...



无论如何,感谢所有人你的建议。如果不出意外,他们会保持头脑旋转,帮助我走向解决方案。
Right, I finally found the problem in my original source code. There were actually two issues:

1. I needed to move the definition of operator+ to a header (created a separate one for all the operator definitions to come). Thanks to Matthew Faithfull for pointing this out.

2. The original version of my VectorExpression3d class was generated by an UML tool, and it had automatically added a (empty) destructor. After removing that destructor, the compiler was finally able to inline my operator+ ! I''m not quite sure, but I suspect the destructor prevented the compiler from treating the class like a POD type...

In any case, thanks for all your suggestions. If nothing else, they kept my head spinning and helped me move towards the solution.


这篇关于是否可以内联一个重载的运算符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆