В настоящее время я использую многопоточность на моем RayTracer, и в одном из моих тестовых примеров начали появляться странные артефакты изображения. Другие три, кажется, работают нормально. Я покажу изображения.
Обычная одиночная резьба:
Многопоточность:
Многопоточность, другой прогон:
Что я делаю - это переключаю пиксели между двумя потоками. Поток 0 получает пар пикселей (0,2,4,6), а поток 1 получает пикселей (1,3,5,9)
Как можно видеть, существует много легких зеленовато-голубоватых артефактов и вариаций между двумя многопоточными прогонами, такими как расположение и количество маленьких точек, таких как артефакты, плюс цвет треугольника.
Я отправляю программу для печати переменных данных, и вот что я получил:
ST:
БОТО x: 402 y 405
БОТО x: 403 y 405
BOTO x: 404 y 405
......
......
БОТО x: 405 y 407
BOTO x: 406 y 407
BOTO 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
BOTO x: 405 y 405
......
......
BOTO x: 404 y 407
BOTO x: 406 y 407
BOTO x: 408 y 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