gpt4 book ai didi

C++ 为什么原始 double 组中的赋值似乎比 double 变量赋值快得多?

转载 作者:行者123 更新时间:2023-11-28 01:21:20 25 4
gpt4 key购买 nike

我正在尝试编写 Mandelbrot 集算法的简化版本。但是通过将每个像素的每个 Z 存储在数组中并使用 Z[n] 计算 Z[n+1] 来计算 Z_n+1 似乎比仅存储 Z_n 以计算 Z_n+1 更快。这对我来说意义不大。

我正在使用 Qt 在 C++ 中对此进行编程,在 Release模式下运行。

版本一(快速):

    // inside QWidget-class
int numberIterations = 500;
double dw = width();
double dh = height();
int iw = width();
int ih = height();
int colors[iw][ih] = {};
double cr = 0.0;
double cc = 0.0;
double zr[numberIterations] = {0.0};
double zc[numberIterations] = {0.0};
for (int x = 0; x < iw; x++) {
for (int y = 0; y < ih; y++) {
cr = ((double)x/dw)*3.0-2.0;
cc = ((double)y/dh)*2.0-1.0;

colors[x][y]=0;

QTime time;
time.start();
for(int n=1; n<numberIterations; n++){

zr[n] = zr[n-1]*zr[n-1] -(zc[n-1]*zc[n-1]) + cr;
zc[n] = zr[n-1]*zc[n-1] + cc;

if(qAbs(zr[n])>2.0 || qAbs(zc[n])>2.0){ // to simplify it
colors[x][y]=1;
break;
}
}
qDebug() << time.elapsed(); // prints almost always 0 (ms)
}
}

如您所见,i 将复数 Z 的实部和 i 部分分开。通过求解二项式,以这种方式计算它真的很容易,但在这种情况下实际上并不重要,因为实际计算是相同的。版本 2(慢):

// ... 
double zr = 0.0;
double zc = 0.0;
double zr_old = 0.0;
for (int x = 0; x < iw; x++) {
for (int y = 0; y < ih; y++) {
cr = ((double)x/dw)*3.0-2.0;
cc = ((double)y/dh)*2.0-1.0;

colors[x][y]=0;

QTime time;
time.start();
for(int n=1; n<numberIterations; n++){

zr_old = zr;
zr = zr*zr -(zc*zc) + cr;
zc = zr_old*zc + cc;

if(qAbs(zr)>2.0 || qAbs(zc)>2.0){
colors[x][y]=1;
break;
}
}
qDebug() << time.elapsed(); // prints about 2 on average (0-6)
}
}

在索引处访问 double 组中的元素比仅使用 double 变量更快,这对我来说听起来真的很奇怪......实际上是这种情况还是我遗漏了一些使内部 for 循环(使用 n ) 使用变量时要慢得多(当然还有一个额外的赋值)?可能我现在只是瞎了眼,但我只是不明白...

编辑 1

正如 Dmytro Dadyka 指出的那样,我的第二个版本是错误的。在数组中,第一个元素始终为零(约定),但是当切换到下一个像素时,我没有将像素循环中的变量归零,这给了我错误的时间进行有意义的计算,因为内部 for 循环的迭代次数是然后更大。它必须是:

    // ...
double zr = 0.0;
double zc = 0.0;
for (int x = 0; x < iw; x++) {
for (int y = 0; y < ih; y++) {
zr = 0.0;
zc = 0.0;
for(int n=1; n<numberIterations; n++){
// ...
}
}
}

但是,此版本计算像素所有值所需的时间仍比数组版本长约 10%。这很奇怪,因为它应该按照 Garf365 指出的那样接受更多指令。

最佳答案

你给出的例子不等同。 zrzc 第一种情况的初始值为 zr[0] = 0, zc[0] = 0并且对于每个 (x, y) 像素都是相同的。在第二种情况下,初始 zrzc 值是前一个像素的最终值。我认为它破坏了计算逻辑,在第二种情况下你得到了错误的迭代计数。通过在循环中初始化 zrzc 修复您的代码:

for (int x = 0; x < iw; x++) {
for (int y = 0; y < ih; y++) {
cr = ((double)x/dw)*3.0-2.0;
cc = ((double)y/dh)*2.0-1.0;
double zr = 0.0;
double zc = 0.0;

关于C++ 为什么原始 double 组中的赋值似乎比 double 变量赋值快得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56128370/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com