目标是用顺序的mandelbrot算法编写并行化。我的数据类型和指针遇到了一些问题。
这就是我的主要c的样子:
int main(int argc, char **argv)
{
/****
Here are initializations and some for my question irrelevant code...
*****/
unsigned char (*image)[x_resolution][3];
image = malloc(x_resolution * y_resolution * sizeof(char[3]));
// compute mandelbrot
mandelbrot_draw(x_resolution, y_resolution, max_iter, view_x0, view_x1,
view_y0, view_y1, x_stepsize, y_stepsize, palette_shift, image,
num_threads);
free(image);
}
我正在努力的第一件事是行unsigned char (*image)[x_resolution][3];
我理解的方式是,我正在用*image
创建指针。我也知道在处理数组中使用括号。但是我并不真正了解我得到的数据类型。
然后我的平行算法以这样的启动:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <complex.h>
#include <pthread.h>
#include "mandelbrot.h"
struct pthread_args_struct
{
int x_resolution;
int y_resolution_lower_boundary;
int y_resolution_upper_boundary;
int max_iter;
double view_x0;
double view_y1;
double x_stepsize;
double y_stepsize;
int palette_shift;
unsigned char** img;
};
我需要这个结构,因为我需要将参数传递给pthreads_create,而且此函数只能获取一个输入参数。我研究了您如何处理结构内的指针,并像这里所建议的那样:在struct
中存储和访问2D阵列我在代码中还具有以下功能:
void mandelbrot_draw(int x_resolution, int y_resolution, int max_iter,
double view_x0, double view_x1, double view_y0, double
view_y1, double x_stepsize, double y_stepsize,
int palette_shift, unsigned char (*img)[x_resolution][3],
int num_threads) {
//I split the image into rows
// and let each thread calculate the pixels for one row
int y_resolution_thread[num_threads+1];
for (int t = 0; t < num_threads; t++)
{
y_resolution_thread[t] = t*(y_resolution/num_threads);
y_resolution_thread[num_threads] = y_resolution;
}
//allocate pthreads space and space for struct
pthread_t *threads = (pthread_t*) malloc (num_threads*sizeof(pthread_t));
struct pthread_args_struct* args = (struct pthread_args_struct*) malloc
(num_threads*sizeof(struct pthread_args_struct));
//create threads, start mandelbrot_draw_row in parallel
for(int i = 0; i < num_threads; ++i) {
args[i].y_resolution_lower_boundary = y_resolution_thread[i];
args[i].y_resolution_upper_boundary = y_resolution_thread[i+1];
args[i].x_resolution = x_resolution;
args[i].max_iter = max_iter;
args[i].view_x0 = view_x0;
args[i].view_y1 = view_y1;
args[i].x_stepsize = x_stepsize;
args[i].y_stepsize = y_stepsize;
args[i].palette_shift = palette_shift;
memcpy(&args[i].img, img, sizeof(img));
//create thread and pass arguments
pthread_create (&threads[i] , NULL, mandelbrot_draw_row, args+i);
}
//wait for finish and join
for (int i = 0; i < num_threads; ++i){
pthread_join(threads[i], (void*)&img);
}
free(threads); free(args);
return((void*) &img);
}
void* mandelbrot_draw_row (void* args){
struct pthread_args_struct* arg = (struct pthread_args_struct*) args;
arg->img = malloc(sizeof(arg->img));
int k;
for (int i = arg->y_resolution_lower_boundary; i < arg->
y_resolution_upper_boundary; i++)
{
for (int j = 0; j < arg->x_resolution; j++)
{
k = 0;
//do some calculations here
if (k == arg->max_iter)
{
memcpy(&args->img[i][j], " ", 3); <- here I get a
segmentation fault
}
else
{
int index = (k + arg->palette_shift)
% (sizeof(colors) / sizeof(colors[0]));
memcpy(&args->img[i][j], colors[index], 3);
}
}
}
return(void*) &arg->img;
}
这是我的主要问题:我在memcpy(&args->img[i][j], " ", 3);
中得到了分段故障。我认为我在这里的指针确实做错了什么,但是我真的不明白我应该做的事情。
您的问题是您的图像点指向一个单个大3D数组。在内存中,这是一大堆值。我试图绘制图片以表示下面的3D阵列。
,但是您正在尝试将其像1D数组的指针到1D数组一样使用。无论哪种方式切成薄片,这都可能无法使用,因为您的数组一开始就没有指针。
您应该更改类型:
unsigned char** img;
使其与main
中的一个:
unsigned char (*image)[x_resolution][3];
然后替换以下:
memcpy(&args[i].img, img, sizeof(img));
仅:
args[i].img = img;
我看到您正在使用Memcpy,因为编译器抱怨您试图将指针分配给其他类型的指针。编译器抱怨是有原因的。