【问题标题】:Mandelbrot using Pthreads, stepping through arrayMandelbrot 使用 Pthreads,遍历数组
【发布时间】:2017-01-29 15:29:20
【问题描述】:

我正在做一个项目来重写一个顺序 C 代码算法,以使用 pthreads 将 mandelbrot 集创建为并行集。可以这么说,我已经碰壁了,因为我的版本只是输出或多或少的黑色图片(与原始程序的结果无关),我真的看不出我哪里出错了。简而言之,我可以用另一双眼睛看这个。

这是重要的顺序代码sn-p:

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];
        }
    }
}

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

这个函数是我真正接触过的唯一一段代码。 main 函数的唯一区别是我在其中创建了线程,并带有执行 Mandel 函数的指令。

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

【问题讨论】:

  • 你在启动线程时是如何传入threadId的?由于您似乎在使用指针,因此您需要在调用 pthread_create() 后保留实际值。例如,如果您使用相同的变量,并在创建每个线程后将其递增,则各个线程可能不会获得正确的值,因为 threadId 指向的位置在值被读入之前已经改变......跨度>
  • 我自己解决了,我会发布更新答案。
  • 但是是的,你确实一针见血:P

标签: c arrays multithreading pthreads mandelbrot


【解决方案1】:

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

不管怎样,问题不在于在函数中单步执行数组,而在于我是如何创建线程的。

这是发生问题时它在 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

只是表明,如果您搜索的时间足够长,而且大部分时间都可以找到您正在寻找的答案。

【讨论】:

    猜你喜欢
    • 2014-07-31
    • 1970-01-01
    • 2023-01-28
    • 1970-01-01
    • 2015-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-31
    相关资源
    最近更新 更多