implemented multithreading, but with mutex. will mit atomic operations optimieren

This commit is contained in:
any
2026-08-28 23:47:46 +02:00
parent 3d1cb713f2
commit 20ab33de33
5 changed files with 93 additions and 27 deletions
+7 -1
View File
@@ -9,6 +9,8 @@
#include <stdlib.h> #include <stdlib.h>
#include "interface.h" #include "interface.h"
#include "helper.h" #include "helper.h"
#include <time.h>
#include <stdio.h>
void example_color(int width, int height, int channels, unsigned char **image) { void example_color(int width, int height, int channels, unsigned char **image) {
for (int i = 0; i < height * width; i++) { for (int i = 0; i < height * width; i++) {
@@ -113,7 +115,11 @@ void exampleCornell( int width, int height, int channels, unsigned char **image)
objectList[18] = (object){1, &(makroObj3.quad6), 0}; objectList[18] = (object){1, &(makroObj3.quad6), 0};
clock_t startTime = clock();
displaySzene(objectList, objectCount, cam1, width, height, channels, image); displaySzene(objectList, objectCount, cam1, width, height, channels, image);
clock_t endTime = clock();
double elapsedTime = (endTime - startTime)/(double)CLOCKS_PER_SEC;
printf("%.3lf\n", elapsedTime);
} }
+67 -24
View File
@@ -9,6 +9,57 @@
#include "raytrace.h" #include "raytrace.h"
#include <stdlib.h> #include <stdlib.h>
#include "helper.h" #include "helper.h"
#include <pthread.h>
#define WORKTHREADSIZE 32
void* renderPixel(RenderArgs *arg, int pixelId) {
RenderArgs *args = (RenderArgs*)arg;
int step = pixelId * args->channels;
int x = pixelId % args->width;
int y = pixelId / args->width;
RGBA pixelColor;
vec3 *pixelOrigin = (vec3 *)malloc(sizeof(vec3));
*pixelOrigin = vec3Add(*args->screenTopLeft,
vec3Add(
vec3Scale(*args->vecPixelStepX, x),
vec3Scale(*args->vecPixelStepY, y)
)
);
ray *lightRay = (ray *)malloc(sizeof(ray));;
lightRay->origin = args->cam1->origin;
lightRay->direction = vec3Normalize(vec3Subtract(*pixelOrigin, args->cam1->origin));
pixelColor = getPixelColor(args->objectList,args->objectCount, lightRay);
free(pixelOrigin);
free(lightRay);
(*args->image)[step] = (int)(pixelColor.r * 255.0);
(*args->image)[step+1] = (int)(pixelColor.g * 255.0);
(*args->image)[step+2] = (int)(pixelColor.b * 255.0);
if (args->channels == 4) {
(*args->image)[step+3] = 255;
}
return NULL;
}
void *workerLoop(void *arg) {
RenderArgs *args = (RenderArgs*)arg;
while (1) {
pthread_mutex_lock(&args->mutexKey);
int pixelId = args->nextPixelId;
args->nextPixelId++;
pthread_mutex_unlock(&args->mutexKey);
if (pixelId >= args->pixelCount) break;
renderPixel(args, pixelId);
}
return NULL;
}
void displaySzene(object objectList[], int objectCount, camera cam1, int width, int height, int channels, unsigned char **image) { void displaySzene(object objectList[], int objectCount, camera cam1, int width, int height, int channels, unsigned char **image) {
const vec3 worldUp = (vec3){0, 1, 0}; const vec3 worldUp = (vec3){0, 1, 0};
@@ -24,34 +75,26 @@ void displaySzene(object objectList[], int objectCount, camera cam1, int width,
double pixelStepY = cam1.height / cam1.resolutionY; double pixelStepY = cam1.height / cam1.resolutionY;
vec3 vecPixelStepX = vec3Scale(screenX, pixelStepX); vec3 vecPixelStepX = vec3Scale(screenX, pixelStepX);
vec3 vecPixelStepY = vec3Scale(screenY, pixelStepY); vec3 vecPixelStepY = vec3Scale(screenY, pixelStepY);
for (int i = 0; i < height * width; i++) {
int step = i *channels;
int x = i % width;
int y = i / width;
RGBA pixelColor;
vec3 *pixelOrigin = (vec3 *)malloc(sizeof(vec3)); pthread_t *threadIdList = (pthread_t *)malloc(sizeof(pthread_t) * WORKTHREADSIZE);
*pixelOrigin = vec3Add(screenTopLeft,
vec3Add(
vec3Scale(vecPixelStepX, x),
vec3Scale(vecPixelStepY, y)
)
);
ray *lightRay = (ray *)malloc(sizeof(ray));;
lightRay->origin = cam1.origin;
lightRay->direction = vec3Normalize(vec3Subtract(*pixelOrigin, cam1.origin));
pixelColor = getPixelColor(objectList,objectCount, lightRay); RenderArgs *args = (RenderArgs*)malloc(sizeof(RenderArgs));
free(pixelOrigin); *args = (RenderArgs){objectList, objectCount, width, channels, &screenTopLeft, &vecPixelStepX, &vecPixelStepY, &cam1, image, 0, 0,width * height};
free(lightRay); pthread_mutex_init(&args->mutexKey, NULL);
//pthread_t threadId;
(*image)[step] = (int)(pixelColor.r * 255.0); for (int i = 0; i < WORKTHREADSIZE; i++) {
(*image)[step+1] = (int)(pixelColor.g * 255.0); pthread_create(&(threadIdList[i]), NULL, workerLoop, args);
(*image)[step+2] = (int)(pixelColor.b * 255.0);
if (channels == 4) {
(*image)[step+3] = 255;
} }
//renderPixel(i, objectList, objectCount, width, channels, &screenTopLeft, &vecPixelStepX, &vecPixelStepY, &cam1, image);
for (int i = 0; i < WORKTHREADSIZE; i++) {
pthread_join(threadIdList[i], NULL);
} }
pthread_mutex_destroy(&args->mutexKey);
free(threadIdList);
free(args);
} }
+1 -1
View File
@@ -8,7 +8,7 @@
#include <math.h> #include <math.h>
#define epsilon 1e-8 #define epsilon 1e-8
#define RAYSPERPIXEL 100 #define RAYSPERPIXEL 100
#define lightBounces 5 #define lightBounces 6
#define GLOBALILLUMINATION 0.3 #define GLOBALILLUMINATION 0.3
enum objectType { enum objectType {
SPHERETYPE, SPHERETYPE,
+17
View File
@@ -1,4 +1,5 @@
#pragma once #pragma once
#include <pthread.h>
struct vec3 { struct vec3 {
double x, y, z; double x, y, z;
}; };
@@ -56,3 +57,19 @@ struct object {
struct cube { struct cube {
quad quad1,quad2,quad3,quad4,quad5,quad6; quad quad1,quad2,quad3,quad4,quad5,quad6;
}; typedef struct cube cube; }; typedef struct cube cube;
typedef struct {
//int pixelId;
object *objectList;
int objectCount;
int width;
int channels;
vec3 *screenTopLeft;
vec3 *vecPixelStepX;
vec3 *vecPixelStepY;
camera *cam1;
unsigned char **image;
int nextPixelId;
pthread_mutex_t mutexKey;
int pixelCount;
} RenderArgs;
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB