asset1

什么是 Mandelbrot ?

“Mandelbrot” 是指 Mandelbrot 集,它是一种在复平面上定义的分形集合,由数学家 Benoit Mandelbrot 在1980年左右首次引入。Mandelbrot 集的定义基于一个简单的复数迭代公式,但它产生的结果却异常复杂和美丽,是分形理论中的一个重要对象。

在编程和计算机图形学中,Mandelbrot 集常常被用来生成视觉上吸引人的图像。这些图像通常通过对每个像素进行迭代计算并根据结果着色来生成。这个过程可以在串行或并行环境中进行,因此经常被用作评估和比较不同计算平台和编程模型性能的基准测试。

在你的代码中,mandelbrotSerial 函数可能就是用来计算并生成 Mandelbrot 集图像的。

Mandelbrot Set

mandel

static inline int mandel(float c_re, float c_im, int count)
{
    float z_re = c_re, z_im = c_im;
    int i;
    for (i = 0; i < count; ++i) {

        if (z_re * z_re + z_im * z_im > 4.f)
            break;

        float new_re = z_re*z_re - z_im*z_im;
        float new_im = 2.f * z_re * z_im;
        z_re = c_re + new_re;
        z_im = c_im + new_im;
    }

    return i;
}

这段代码定义了一个名为 mandel 的函数,它用于计算一个给定的复数是否属于 Mandelbrot 集。如果一个复数属于 Mandelbrot 集,那么对它进行一系列的运算,结果会始终保持在一个有限的范围内。否则,结果会趋向于无穷大。

函数接收三个参数:c_rec_im 是复数的实部和虚部,count 是最大迭代次数。函数返回一个整数,表示复数被排除出 Mandelbrot 集所需的迭代次数。

在函数内部,首先定义了两个变量 z_rez_im,并将它们初始化为 c_rec_im。然后,进入一个最多执行 count 次的循环。

在每次循环中,首先检查 z_rez_im 的平方和是否大于4。如果大于4,那么就跳出循环。这是因为,如果一个复数的模大于2,那么它就不属于 Mandelbrot 集。

如果 z_rez_im 的平方和不大于4,那么就计算新的 z_rez_im 的值。新的 z_rez_re 的平方减去 z_im 的平方,新的 z_im2.f * z_re * z_im。然后,将 c_rec_im 分别加到新的 z_rez_im 上。

循环结束后,返回 i,即复数被排除出 Mandelbrot 集所需的迭代次数。如果 i 等于 count,那么可以认为这个复数属于 Mandelbrot 集。

实话实说没太看懂,这个 Mandelbrot 集是什么东西,但是这个函数的功能还是能看懂的.

多线程优化

抄袭的PKU的代码,使用多线程优化mandelbrotSerial函数,先使用diff比较一下几个文件的不同之处

// StepSerial函数的作用就是让各个线程计算的负担较为平均

❯ diff asst1/prog1_mandelbrot_threads/mandelbrotSerial.cpp  asst1_pk/prog1_mandelbrot_threads/mandelbrotSerial.cpp
92a93,112
> void mandelbrotStepSerial(
>     float x0, float y0, float x1, float y1,
>     int width, int height,
>     int startRow, int step,
>     int maxIterations,
>     int output[])
> {
>     float dx = (x1 - x0) / width;
>     float dy = (y1 - y0) / height;
>
>     for (int j = startRow; j < height; j+=step) {
>         for (int i = 0; i < width; ++i) {
>             float x = x0 + i * dx;
>             float y = y0 + j * dy;
>
>             int index = (j * width + i);
>             output[index] = mandel(x, y, maxIterations);
>         }
>     }
> }

worker thread

不太懂cpp的std::thread,我直接来通过问GPT来解决这个库的使用问题(当然本身线程的概念我是懂的,就是不太懂这个库的使用方法) “Worker thread” 是一种常见的并发编程模型中的术语,它指的是被创建出来执行特定任务的线程。这些任务通常是独立的,可以并行执行,不需要等待其他线程的结果。

在你给出的代码中,workerThreadStart 函数可能是每个 worker thread 的入口点。这个函数接收一个 WorkerArgs 指针作为参数,这个指针可能包含了 worker thread 需要的所有信息,例如线程 ID、需要计算的图像的大小和位置等。

在函数体内,首先获取当前的时间,然后注释中提到了两种可能的方法来分配给每个 worker thread 的计算任务。这些任务是计算 Mandelbrot 集的一部分,并将结果存储在输出图像中。

需要注意的是,虽然这个函数的具体实现还没有给出,但从函数的名称和注释中可以看出,它的主要任务是为每个 worker thread 分配计算任务,并调用 mandelbrotSerial 函数来执行这些任务。