【发布时间】:2011-12-04 23:03:35
【问题描述】:
在我正在编写的软件中,我正在对我的值进行数百万次乘法或除以 2(或 2 的幂)。我真的希望这些值是 int 以便我可以访问位移运算符
int a = 1;
int b = a<<24
但是,我不能,我必须坚持双打。
我的问题是:由于有标准的双精度表示(符号、指数、尾数),有没有办法使用指数来获得 2 的幂的快速乘法/除法 ?
我什至可以假设位数将是固定的(该软件将在始终具有 64 位长双精度的机器上运行)
P.S : 是的,算法大多只做这些操作。这是瓶颈(它已经是多线程的了)。
编辑:还是我完全弄错了,聪明的编译器已经为我优化了?
临时结果(用Qt来测量时间,矫枉过正,但我不在乎):
#include <QtCore/QCoreApplication>
#include <QtCore/QElapsedTimer>
#include <QtCore/QDebug>
#include <iostream>
#include <math.h>
using namespace std;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
while(true)
{
QElapsedTimer timer;
timer.start();
int n=100000000;
volatile double d=12.4;
volatile double D;
for(unsigned int i=0; i<n; ++i)
{
//D = d*32; // 200 ms
//D = d*(1<<5); // 200 ms
D = ldexp (d,5); // 6000 ms
}
qDebug() << "The operation took" << timer.elapsed() << "milliseconds";
}
return a.exec();
}
运行表明D = d*(1<<5); 和D = d*32; 同时运行(200 毫秒),而D = ldexp (d,5); 则慢得多(6000 毫秒)。我知道这是一个微基准测试,突然间,我的 RAM 爆炸了,因为 Chrome 突然要求在我每次运行 ldexp() 时计算 Pi,所以这个基准测试毫无价值.不过我还是会留着的。
另一方面,我在执行 reinterpret_cast<uint64_t *> 时遇到问题,因为存在 const 违规(似乎 volatile 关键字干扰)
【问题讨论】:
-
不要仅仅因为它是多线程的就认为它是瓶颈。我们有一个多线程应用程序,我们发现它在许多地方都出现了与我们预期不同的瓶颈?您的分析准确度如何?
-
与往常一样,对应用程序的分析永远不够。我的意思是,我使用了 CacheGrind,而且似乎我大部分时间都花在了一个主要用于乘法运算的函数上。它似乎。但我写道这是瓶颈,因为我对乘以 2 背后的理论思想更感兴趣,而不是“琐碎的考虑”(当然,我可以优化我的 SQL 请求,但老实说,我很确定它会与乘法相比毫无意义,而且大多数情况下,我不在乎 ^^)
-
是的,我“知道” ^^ 但是有人说你可以用奇怪的东西混淆编译器(基本上,一些操作归结为
*32,但编译器没有“看到”它)。这只是一行=) -
除了
I used CacheGrind, and it seems I spend most of my time in a function that does mostly multiplications,我还能说什么呢?是的,当然,这个函数也做加法,并在栈上分配数据,但我想我对情况有一个很好的估计。 -
@Fezvez: 1) 你的循环需要展开。 2) CacheGrind 说你主要是在一些数学例程中?那是警报!在汇编语言级别单步执行代码,并确保它没有超出您的预期。它不应该调用anything。 3)多线程不会使代码更快。它充其量只是将其分散在更多的处理器上。 4) 如果性能是你真正关心的,learn this technique.
标签: c++ c optimization division multiplication