трассировка лучей с использованием pthreads

#gcc #pthreads #raytracing

#gcc #pthreads #трассировка лучей

Вопрос:

 int main(int a, char *args[]) {
    int i;
    pthread_t threads[8];
    unsigned int* pixmap = malloc(1024*1024*sizeof(int));

    v_threadargs.height = 1024.0f;
    v_threadargs.width = 1024.0f;
    v_threadargs.pixmap = pixmap;

    for (i = 0; i < 8; i  ) {
        v_threadargs.threadid = i;
        pthread_create(amp;threads[i], NULL, render, (void *) amp;v_threadargs);
    }

    for (i = 0; i < 8; i  )
        pthread_join(threads[i], NULL);

    writetga(pixmap, 1024, 1024, "ray8out.tga");
    free(pixmap);

    pthread_exit(NULL);
    return 0;
}

void *render(void *r_threadargs) {
    int i,j, threadid, start;
    float height, width;
    int *pixmap;

    struct s_threadargs *p_threadargs;
    p_threadargs = (struct s_threadargs *) r_threadargs;
    height = p_threadargs -> height;
    width = p_threadargs -> width;
    pixmap = p_threadargs -> pixmap;
    threadid = p_threadargs -> threadid;

    stepy = viewplaney0;
    deltax = (viewplanex1 - viewplanex0) / width;
    deltay = (viewplaney1 - viewplaney0) / height;
    stepy  = deltay;

    float *viewer = (float[3]){0.0f, 0.0f, -7.0f};

    if (threadid == 1)
        start = 0;
    else
        start = threadid * height/8;

    for (i = start; i < (threadid   1)*(height/8); i  ) {
        stepx = viewplanex0;
        for (j = 0; j < width; j  ) {
            float *color = (float[3]){0.0f, 0.0f, 0.0f};
            float *raydir = (float[3]){stepx - viewer[0], stepy - viewer[1], 0 - viewer[2]};
            float maxdist = 100000.0f;
            normalize(raydir);
            trace(raydir, viewer, color,  0,maxdist);
            int r = (int)(roundf(color[0]*255.0f));
            if (r > 255) { r = 255; }
            int g = (int)(roundf(color[1]*255.0f));
            if (g > 255) { g = 255; }
            int b = (int)(roundf(color[2]*255.0f));
            if (b > 255) { b = 255; }
            pixmap[j i*(int)width] = (r << 16) | (g << 8) | (b);
            stepx  = deltax;
        }
        stepy  = deltay;
    }
}
  

Я пытаюсь реализовать эту программу raytracer с использованием 8 потоков (pthreads с использованием gcc), но выводимое изображение «ray8out.tga» неверно. Программа выполняется корректно, без каких-либо ошибок, но чего-то не хватает в логике. Было бы приятно, если бы кто-нибудь, пожалуйста, мог мне помочь, где ошибка?

Ответ №1:

Вы передаете одну и ту же структуру threadargs каждому потоку; нет гарантии, что они начнут выполняться до того, как вы измените значение threadid. Вы должны выделить новую структуру threadargs с помощью malloc для каждого потока (и освободить ее внутри самого нового потока).

Комментарии:

1. На самом деле я новичок в потоках. Вы имеете в виду, что: для (i = 0; i < 8; i ) { v_threadargs[i].height = 1024.0f; v_threadargs [i].width = 1024.0f; v_threadargs[i].pixmap = пиксельная карта; v_threadargs[i].threadid = i; pthread_create (amp;потоки [i], NULL, визуализация, (void *) amp; v_threadargs[i]); }

2. @Bilal, да, использование массива — это вариант, а также до тех пор, пока v_threadargs остается неизменным, пока все потоки не будут объединены.