Цель состоит в том, чтобы написать распараллеливание из последовательного алгоритма Мандельброта. У меня проблемы с типами данных и указателями.
Вот так выглядит мой main.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, и эта функция может получить только один аргумент для ввода. Я исследовал, как вы можете работать с указателем внутри структуры, и сделал это, как предложено здесь: Хранение и доступ к 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], "\0\0\0", 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], "\0\0\0", 3);
. Я думаю, что я делаю что-то действительно не так с указателями, но я не могу понять, что я должен делать.