我正在尝试编写 Mandelbrot 集算法的简化版本。但是,通过将一个像素的每个 Z 存储在一个数组中并使用 Z[n] 计算 Z[n+1] 来计算 Z_n+1 似乎比仅存储 Z_n 来计算 Z_n+1 更快。这对我来说没有多大意义。
我正在用 Qt 用 C++ 编程,在发布模式下运行。
版本一(快速):
// 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)
}
}
如您所见,我将复数 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)慢得多的东西何时使用变量(当然还有一项额外的赋值)?也许我现在只是瞎了,但我只是不明白……
正如 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 指出的那样需要更多的说明。
你给出的例子并不等同。第一种情况下的初始值zr
和zc
值是zr[0] = 0
,zc[0] = 0
并且每个(x, y)
像素都相同。在第二种情况下,初始值zr
和zc
值是前一个像素的最终值。我认为它破坏了计算逻辑,并且在第二种情况下您会得到错误的迭代计数。通过zr
并zc
在循环中初始化来修复您的代码:
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;
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句