c - Mandelbrot 使用 Pthreads,单步遍历数组

标签 c arrays multithreading pthreads mandelbrot

我正在开展一个项目,重写顺序 C 代码算法,以使用 pthreads 将 mandelbrot 集创建为并行集。可以说,我已经碰壁了,因为我的版本只是输出一张或多或少的黑色图片(与原始程序的结果没有什么不同),而且我真的看不出我哪里出了问题。简而言之,我可以用第二双眼睛来观察这个。

这是重要的顺序代码片段:

void mandelbrot(float width, float height, unsigned int *pixmap)
{
int i, j;
float xmin = -1.6f;
float xmax = 1.6f;
float ymin = -1.6f;
float ymax = 1.6f;
for (i = 0; i < height; i++) {
    for (j = 0; j < width; j++) {
        float b = xmin + j * (xmax - xmin) / width;
        float a = ymin + i * (ymax - ymin) / height;
        float sx = 0.0f;
        float sy = 0.0f;
        int ii = 0;
        while (sx + sy <= 64.0f) {
            float xn = sx * sx - sy * sy + b;
            float yn = 2 * sx * sy + a;
            sx = xn;
            sy = yn;
            ii++;
            if (ii == 1500) {
                break;
            }
        }
        if (ii == 1500) {
            pixmap[j+i*(int)width] = 0;
        }
        else {
            int c = (int)((ii / 32.0f) * 256.0f);
            pixmap[j + i *(int)width] = pal[c%256];
        }
    }
}


}

这是我的代码的顺序版本:

void* Mandel(void* threadId) {
    int x = *(int*)threadId;
    float xmin = -1.6f;
    float xmax = 1.6f;
    float ymin = -1.6f;
    float ymax = 1.6f;

    float b = xmin + x * (xmax - xmin) / WIDTH;
    for (int y = 0; y < 1024; y++)
    {
        float a = ymin + y * (ymax - ymin) / WIDTH;
        float sx = 0.0f;
        float sy = 0.0f;
        int ii = 0;
        while (sx + sy <= 64.0f) {
            float xn = sx * sx - sy * sy + b;
            float yn = 2 * sx * sy + a;
            sx = xn;
            sy = yn;
            ii++;
            if (ii == 1500) {
                break;
            }
        }
        if (ii == 1500) {
            pixmap[x+y*(int)WIDTH] = 0;
        }
        else {
            int c = (int)((ii / 32.0f) * 256.0f);
            pixmap[x + y *(int)WIDTH] = pal[c%256];
        }
    }
}

我的思考过程的解释: 我在 main 函数中创建了 1024 个线程,然后用每个线程调用上面的函数。它们应该各占一列(因为 x 是 0 到 1023 之间的常数,而 y 值在函数内从 0 变化到 1023)。正如您所看到的,函数本身的大部分数学内容在代码的顺序版本和并行版本中都是相同的。因此,我认为问题出在我如何逐步遍历数组,但我无法用自己的眼睛看到问题。无论如何,ii 最终收到的值将用于计算 c,c 又用于决定要保存在像素图中相应位置的颜色值。 (pal 基本上只是一个充满颜色值的大数组)。

这个函数是我在很大程度上实际接触过的唯一一段代码。 main 函数中唯一的区别是我在其中创建了线程,并使用执行 Mandel 函数的指令。

我认为任何愿意提供帮助的人都会需要更多信息,如果我发布的信息太少,请告诉我这篇文章的任何改进。

最佳答案

我在发布此代码后不久就找到了答案。我真傻。

无论如何,问题不在于单步执行函数内的数组,而在于我如何创建线程。

这是问题发生时 main 中的样子:

for(int k = 0; k < 1024; k++) {
    pthread_create(&threads[k], NULL, (void*)Mandel, (void*) k);
}

这样做的问题是循环继续,改变下一个线程的 k 值,这意味着我们刚刚创建的最后一个线程突然得到了错误的 k 值。这是通过使用 int 数组解决的,该数组在我们遍历每个 k 值并创建每个线程时保存 k 的值,如下所示:

int id[1024];
for(int k = 0; k < 1024; k++) {
    pthread_create(&threads[k], NULL, (void*)Mandel, (void*)(id+k));
}

我想指出以下链接中的帖子,以帮助我回答这个问题: Pass integer value through pthread_create

只是为了表明,如果您搜索得足够长,在大多数情况下,您通常可以找到您正在寻找的答案。

关于c - Mandelbrot 使用 Pthreads,单步遍历数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41922563/

相关文章:

java - 累积所有 float

c++ - 如何使用具有递归模板函数的线程

java - 如何在 AsyncTask 中使用 Runnable.wait()?为什么 AsyncTask 不等待...?

java - 以所有七种方式反射(reflect)方阵八分圆的算法

c++ - 关于 pthread_cond_wait?

c - 使用 & 与数组返回意外结果

c - 使用 STM32 进行 SPI 的 DMA 时数据无效

c - 枚举对象设置为不等于其各自枚举常量的值

c - 如何使用共享内存传递数据并将接收到的数据保存到文件

arrays - 数组标识 - 是