我正在开发一个项目来重写一个顺序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又用于决定要保存在pixmap中相应位置的颜色值。 (pal基本上只是一个填充颜色值的大型数组)。
这个函数是我实际触及到任何主要程度的唯一代码。主要功能的唯一区别是我在其中创建了带有执行Mandel函数的指令的线程。
我认为任何愿意提供帮助的人都会想要更多信息,如果我发布的信息太少,请告诉我这篇文章的任何改进。
答案 0 :(得分:0)
我在发布此代码后不久找到了答案。傻我。
Anywho,问题不是单步执行函数中的数组,而是实际上我是如何创建线程的。
这是问题发生时的主要内容:
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
只是表明,如果你搜索的时间足够长,你可以经常找到你正在寻找的答案。