手动编写循环与运算符重载的效率
在我正在开发的程序中,我有 3 元素数组,我将其用作数学向量用于所有意图和目的。
在编写代码的过程中,我很想使用简单的算术重载(+、-、* /
)来创建自己的 Vector
类,这样我就可以简化如下语句: :
// old:
for (int i = 0; i < 3; i++)
r[i] = r1[i] - r2[i];
// new:
r = r1 - r2;
生成的代码应该或多或少相同。但当涉及到更复杂的事情时,这真的会严重影响我的表现吗?我的代码中的一个例子是这样的:
手动编写的版本:
for (int j = 0; j < 3; j++)
{
p.vel[j] = p.oldVel[j] + (p.oldAcc[j] + p.acc[j]) * dt2 + (p.oldJerk[j] - p.jerk[j]) * dt12;
p.pos[j] = p.oldPos[j] + (p.oldVel[j] + p.vel[j]) * dt2 + (p.oldAcc[j] - p.acc[j]) * dt12;
}
使用带有运算符重载的 Vector
类:
p.vel = p.oldVel + (p.oldAcc + p.acc) * dt2 + (p.oldJerk - p.jerk) * dt12;
p.pos = p.oldPos + (p.oldVel + p.vel) * dt2 + (p.oldAcc - p.acc) * dt12;
我正在尝试优化我的代码以提高速度,因为这种代码在内循环内部运行。使用重载运算符来处理这些事情会影响性能吗?我正在对 n 个相互引力体的系统进行数值积分。这些向量运算非常常见,因此快速运行非常重要。
任何见解以及我不知道的任何习语或技巧都将受到赞赏。
in the program I'm working on I have 3-element arrays, which I use as mathematical vectors for all intents and purposes.
Through the course of writing my code, I was tempted to just roll my own Vector
class with simple arithmetic overloads (+, -, * /
) so I can simplify statements like:
// old:
for (int i = 0; i < 3; i++)
r[i] = r1[i] - r2[i];
// new:
r = r1 - r2;
Which should be more or less identical in generated code. But when it comes to more complicated things, could this really impact my performance heavily? One example that I have in my code is this:
Manually written version:
for (int j = 0; j < 3; j++)
{
p.vel[j] = p.oldVel[j] + (p.oldAcc[j] + p.acc[j]) * dt2 + (p.oldJerk[j] - p.jerk[j]) * dt12;
p.pos[j] = p.oldPos[j] + (p.oldVel[j] + p.vel[j]) * dt2 + (p.oldAcc[j] - p.acc[j]) * dt12;
}
Using the Vector
class with operator overloads:
p.vel = p.oldVel + (p.oldAcc + p.acc) * dt2 + (p.oldJerk - p.jerk) * dt12;
p.pos = p.oldPos + (p.oldVel + p.vel) * dt2 + (p.oldAcc - p.acc) * dt12;
I am attempting to optimize my code for speed, since this sort of code runs inside of inner loops. Will using the overloaded operators for these things affect performance? I'm doing some numerical integration of a system of n mutually gravitating bodies. These vector operations are extremely common so having this run fast is important.
Any insight would be appreciated, as would any idioms or tricks I'm unaware of.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果编译器对操作进行了内联和优化,那么您通常不会发现良好编写代码(使用运算符使其可读和可维护)与手动内联所有内容之间有任何区别。
手动内联还会大大增加出现错误的风险,因为您不会重复使用经过良好测试的代码,而是会一遍又一遍地编写相同的代码。我建议使用运算符编写代码,然后如果您可以证明可以通过手动内联来加快速度,复制代码并手动内联第二个版本。然后,您可以相互运行代码的两个变体,以证明 (a) 手动内联是有效的,以及 (b) 可读的代码和手动内联的代码都产生相同的结果。
不过,在开始手动内联之前,有一个简单的方法可以让您自己回答问题:以两种方式编写一些简单的测试用例,然后执行几百万次迭代,看看哪种方法执行得更快。这将告诉您很多有关正在发生的事情的信息,并为您的特定实现和编译器提供明确的答案,而您将永远无法从此处收到的理论答案中得到这些答案。
If the operations are inlined and optimised well by your compiler you shouldn't usually see any difference between writing the code well (using operators to make it readable and maintainable) and manually inlining everything.
Manual inlining also considerably increases the risk of bugs because you won't be re-using a single piece of well-tested code, you'll be writing the same code over and over. I would recommend writing the code with operators, and then if you can prove you can speed it up by manually inlining, duplicate the code and manually inline the second version. Then you can run the two variants of the code off against each other to prove (a) that the manual inlining is effective, and (b) that the readable and manually-inlined code both produce the same result.
Before you start manually inlining, though, there's an easy way for you to answer your question for yourself: Write a few simple test cases both ways, then execute a few million iterations and see which approach executes faster. This will teach you a lot about what's going on and give you a definite answer for your particular implementation and compiler that you will never get from the theoretical answers you'll receive here.
我想反过来看;从 Vector 类开始,如果遇到性能问题,您可以查看手动内联计算是否更快。
除了性能之外,您还提到计算必须准确。在类中包含特定于向量的计算意味着更容易单独测试这些计算,而且使用该类的代码会变得更短且更易于维护。
I would like to look at it the other way around; starting with the Vector class, and if you get performance problems with that you can see if manually inlining the calculations is faster.
Aside from the performance you also mention that the calculations has to be accurate. Having the vector specific calculations in a class means that it's easier to test those individually, and also that the code using the class gets shorter and easier to maintain.
查看 ConCRT 代码示例
http://code.msdn。 microsoft.com/concrtextras/Release/ProjectReleases.aspx?ReleaseId=4270
有几个(包括 NBody 示例)可以使用 Vector 类型和模板等执行一系列类似的技巧。
Check out the ConCRT code samples
http://code.msdn.microsoft.com/concrtextras/Release/ProjectReleases.aspx?ReleaseId=4270
There's a couple (including an NBody sample) which do a bunch of tricks like this with Vector types and templates etc.