Я делаю многопоточность MT Ray-Tracer, и, как говорится в заголовке, для его выполнения требуется вдвое больше, чем для однопоточной версии. Очевидно, что цель состоит в том, чтобы сократить время рендеринга вдвое, однако сейчас я просто отправляю метод трассировки лучей дважды, по одному для каждого потока, в основном выполняя один и тот же рендеринг дважды. Тем не менее, поскольку потоки могут работать параллельно, не должно быть значительного увеличения времени выполнения. Но о удвоении.
Это должно быть связано с моей настройкой многопоточности. Я думаю, это связано с тем, что я создаю их как объединяемые. Поэтому я собираюсь объяснить, что я делаю, а также добавить соответствующий код, чтобы посмотреть, сможет ли кто-нибудь подтвердить, что это проблема.
Я создаю два потока и устанавливаю их как объединяемые. Создайте RayTracer, который выделяет достаточно памяти для хранения пикселей изображения (это делается в конструкторе). Запустите цикл из двух итераций для отправки соответствующей информации для каждого потока, например, идентификатора потока и адреса экземпляра Raytracer.
Затем pthread_create вызывает run_thread, цель которого - вызвать метод ray_tracer: draw, где работа выполнена. На методе розыгрыша у меня есть
pthread_exit (NULL);
как последняя вещь на нем (единственная вещь MT на этом). Затем сделайте еще один цикл, чтобы присоединиться к потокам. Наконец я начинаю писать файл в маленьком цикле. Наконец закройте файл и удалите указатели, относящиеся к массиву, используемому для хранения изображения в методе draw.
Мне, возможно, не нужно использовать для присоединения сейчас, когда я не делаю «настоящий» многопоточный трассировщик лучей, просто рендеринг его дважды, но как только я начинаю чередовать пиксели изображения (то есть, thread0 -> рендерит pixel0 - thread0 -> сохраняет pixel0, thread1 -> отображает pixel1 - thread1 -> сохраняет pixel1, thread0 -> отображает pixel2 - thread0 -> сохраняет pixel2,, thread1 -> отображает pixel3 - thread1 -> сохраняет pixel3 и т. д.) I думаю, мне это понадобится, чтобы можно было писать пиксели в правильном порядке в файле.
Это правильно? Мне действительно нужно использовать соединение здесь с моим методом (или с любым другим?). Если я это сделаю, как я могу отправить потоки для одновременной работы, не дожидаясь завершения других? Проблема совершенно не связана с присоединением?
pthread_t threads [2];
thread_data td_array [2];
pthread_attr_t attr;
void *status;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
TGAManager tgaManager ("z.tga",true);
if (tgaManager.isFileOpen()) {
tgaManager.writeHeadersData (image);
RayTracer rt (image.getHeight() * image.getWidth());
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);
}
pthread_attr_destroy(&attr);
for (int i=0; i<2; i++ ) {
rc = pthread_join(threads[i], &status);
if (rc) {
cout << "Error:unable to join," << rc << endl;
exit(-1);
}
}
//tgaManager.writeImage (rt,image.getSize());
for (int i=0; i<image.getWidth() * image.getHeight(); i++) {
cout << i << endl;
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 ();
}