有没有c++函数(内置或其他)可以给出整数除法和模除法结果而不重复运算?
您可以这样写:
int i = 3;
int k = 2;
int division = i / k;
int remainder = i % k;
似乎认为这会在较低的级别上要求 ALU 执行两项视觉操作:一项返回商,一项返回余数。然而,我相信 ALU 很可能会在一次操作中计算这两者。如果是这种情况,这并不是最佳效率。
有没有更有效的方法来做到这一点,而不要求CPU计算两次?换句话说,可以通过 C++ 的单个操作来完成吗?
You could write something like:
int i = 3;
int k = 2;
int division = i / k;
int remainder = i % k;
It seems as thought this would, on a low level, ask an ALU to perform two vision operations: one returning the quotient, and one returning the remainder. However, I believe an ALU would most likely calculate both in a single operation. If that is the case, this is not optimally efficient.
Is there a more efficient way of doing it, without asking the CPU to calculate twice? In other words, can it be done in a single operation from C++?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
实际上,您编写的代码不会生成任何除法指令,因为编译器可以在编译时计算出结果。我编写了一个小测试程序并设置编译器(VC++ 10SP1)来生成汇编代码列表。
我必须这样编写它并明确告诉编译器不要内联任何函数。
否则编译器会很高兴地优化掉大部分代码。这是除法函数的最终汇编代码。
它足够智能,可以生成单个 IDIV 指令并使用它生成的商和余数。现代 C 和 C++ 编译器非常擅长这种优化。除非您遇到性能问题并且已经分析了代码以确定瓶颈所在,否则不要尝试再次猜测编译器。
Actually, the code you wrote won't generate any division instructions since the compiler can figure out the results at compile time. I wrote a little test program and set the compiler (VC++ 10SP1) to generate an assembly code listing.
I had to write it this way and explicitly tell the compiler to not inline any functions.
Otherwise the compiler would have happily optimized away most of the code. Here is the resulting assembly code for the divide function.
It's smart enough to generate a single IDIV instruction and use the quotient and remainder generated by it. Modern C and C++ compilers have gotten really good at this sort of optimization. Unless you have a performance problem and have profiled your code to determine where the bottleneck is, don't try to second guess the compiler.
ISO C99 具有
ldiv
功能:是否在 FPU 级别减少到单个操作我不能说。
ISO C99 has the
ldiv
function:Whether at the FPU level that reduces to a single operation I couldn't say.
当然:
另外,如果您确实想这样做,请查看
div
,我怀疑它是否更快,就像我上面的解决方案一样。Sure:
Also, if you really want to do this, look at
div
, I doubt it's faster though, just like my above solution.我不知道任何内置的东西,但你可以用乘法而不是除法来模拟它:
I'm not aware of anything built-in, but you can simulate it with a multiply instead of a divide:
当你问自己什么是最快时,通常最好对其进行基准测试(我喜欢这样做)。因此,我从这里获取了答案,编写了一个小型基准测试程序,并将其扔到
gcc
上(我认为g++
应该有类似的结果)在-O0< /code> (在
-O1
他优化了所有内容,我的基准测试被破坏了)。我执行了
2^28
运行(i
和k
均从1
运行到2^14< /code>) 在我的笔记本电脑上运行,得到以下运行时间:
1.676s
24.614s
15.009s
18.845s
正如我们所看到的,存在差异,最好的办法是乘法 方法。
ldiv
方法也不错,但我发现它与其他方法相比稍微麻烦一些。When you ask yourself, what is fastest, it's usually a good idea to benchmark it (I like to do that). So I took the answers from here and wrote a tiny benchmarking program and threw it at
gcc
(similar results would be expected forg++
I think) at-O0
(at-O1
he optimises everything away and my benchmark is broken).I performed
2^28
runs (bothi
andk
running from1
to2^14
) on my laptop and got the following runtimes:1.676s
24.614s
15.009s
18.845s
As one can see, there is a difference and your best shot is the multiplication approach. The
ldiv
approach is also okay, but I find it slightly cumbersome compared to the others.