MultiThreading RayTracer генерирует странные артефакты с плоскостью
В настоящее время я использую многопоточность в своем RayTracer, и в одном из моих тестовых случаев начали появляться странные артефакты изображения. Другие три, кажется, работают нормально. Я покажу изображения.
Обычная одиночная тема:
Многопоточность:
Многопоточность, другой прогон:
Что я делаю, так это переключаюсь между пикселями между двумя потоками. Поток 0 получает пар пикселей (0,2,4,6), а поток 1 получает пикселей (1,3,5,9)
Как можно видеть, есть много легких зеленовато-голубоватых артефактов и вариаций между двумя многопоточными прогонами, такими как расположение и количество маленькой точки, как артефакты, плюс цвет треугольника.
Я отправляю программу для печати переменных данных, и вот что я получил:
ST:
БОТО x: 402 y 405
БОТО x: 403 y 405
БОТО x: 404 y 405
......
......
БОТО x: 405 y 407
БОТО x: 406 и 407
БОТО x: 407 y 407
Теперь это результат бега на 1° MT:
BOTO x: 403 y 405 thread_id: 1
BOTO x: 403 y 405 thread_id: 1
BOTO x: 403 y 405 thread_id: 1
BOTO x: 403 y 405 thread_id: 1
....
....
BOTO x: 403 y 405 thread_id: 1
BOTO x: 403 y 405 thread_id: 1
BOTO x: 403 y 405 thread_id: 1
BOTO x: 403 y 405 thread_id: 1
И это 2° бега:
БОТО x: 401 y 405
БОТО x: 403 y 405
БОТО x: 405 y 405
......
......
БОТО x: 404 y 407
БОТО x: 406 и 407
БОТО x: 408 и 407
Итак, у меня есть MT-код, который каждый раз выполняется по-разному, поскольку разные изображения показали, что это так. Прогон 2° MT выполняется правильно (без повторяющихся сообщений о координатах экрана) для координат экрана, которые я показал, как в случае ST, но показал то же поведение в отношении других координат.
Более странным является то, что если просто отправить код установки MT для выполнения того же алгоритма, что и в версии ST, или, другими словами, для визуализации одного и того же изображения дважды, проблема не устраняется. И немного меняется.
Как можно видеть, выполнение одного и того же кода с помощью MT иногда приводит к появлению "чистой" области в начале, и треугольник темнеет (хотя я думаю, что возможно, что то же самое может случиться с исходным кодом MT, особенно с "темным" материалом треугольника).
Я был бы признателен за любые предложения о том, как я буду пытаться диагностировать проблему, потому что я не знаю, каков источник проблем, если это связано с кодом установки MT или проблемой алгоритма. Я бы поспорил в коде установки MT, так как это я изменил алгоритм на ту же версию ST, и все еще есть проблемы. Тем не менее, проблемы немного изменились, поэтому я потерян здесь.
Код алгоритма RT, связанный с поддержкой MT:
void RayTracer::draw_multithread (Image *image, Scene *scene, int thread_id) {
float inv_div=0.5;
int ctr=0;
int y=0;
int initial_x=0;
if (thread_id==1) {
cout << "thread_1" << endl;
ctr=1024*384;
y=384;
inv_div=1;
}
//if (thread_id==1)
// return;
for (; y<(float)image->getHeight()*inv_div; y++) {
//float px = px_inicial;
//py = py + ystep;
for (int x=initial_x; x<image->getWidth(); x++) {
....
.....
b [ctr] = min (blue*255.0f,255.0f);
c [ctr] = min (green*255.0f,255.0f);
d [ctr] = min (red*255.0f,255.0f);
ctr++;
}
}
pthread_exit (NULL);
}
MT code:
pthread_t threads [2];
thread_data td_array [2];
void *status;
TGAManager tgaManager ("z.tga",true);
if (tgaManager.isFileOpen()) {
tgaManager.writeHeadersData (image);
RayTracer rt (image.getHeight() * image.getWidth(),1);
int rc;
for (int i=0; i<2; i++) {
//cout << "main() : creating thread, " << i << endl;
td_array[i].thread_id=i;
td_array[i].rt_ptr = &rt;
td_array[i].img_ptr = ℑ
td_array[i].scene_ptr = &scene;
//cout << "td_array.thread_index: " << td_array[i].thread_id << endl;
rc = pthread_create (&threads[i], NULL, RayTracer::run_thread, &td_array[i]);
}
if (rc) {
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
for (int i=0; i<2; i++ ) {
rc = pthread_join(threads[i], &status);
if (rc) {
cout << "Error:unable to join," << rc << endl;
exit(-1);
}
}
for (int i=0; i<image.getWidth() * image.getHeight(); i++) {
tgaManager.file_writer.put (rt.b[i]);
tgaManager.file_writer.put (rt.c[i]);
tgaManager.file_writer.put (rt.d[i]);
}
tgaManager.closeFile(1);
rt.deleteImgPtr (true);
}
Для получения дополнительной информации: https://gitlab.com/asmf2/asmfrt/blob/master/RayTracer.cpp (последний метод снизу вверх) и https://gitlab.com/asmf2/asmfrt/blob/master/main.cpp