【发布时间】: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