Я пытался ускорить код используя OpenMP, но я получил довольно разочаровывающие результаты, и из этого обсуждения на Github я считаю, что другие добились большего ускорения.
Вот что сообщают некоторые пользователи, которых я видел до сих пор :
Также стоит отметить, что изменения очень локальны: запись в буфер вместо строки std::cout; новый метод записи буфера в файл; одна строка OpenMP выше для цикла по строкам выходного изображения.
Мне удалось добиться значительного ускорения, необходимость что стало болезненно очевидным в финальной сцене второй книги, когда использовался #pragma omp Parallel перед циклом с несколькими выборками
С OpenMP вы можете добиться этого с помощью двух строк OpenMP. аннотаций и ни одного изменения в самом коде
Используя эти стратегии, мне не удалось добиться существенного ускорения.
Я сделал копию последней версии репозитория Github (v4.0.1) и поработал над разделом «За одни выходные».
Я добавил аннотацию #pragma omp параллельный для сокращение(+:pixel_color) вокруг образца цикла for (имеет заголовок for (int sample = 0; sample < sample_per_pixel; sample++)) и заголовок #pragma omp объявляет сокращение(+ : vec3 : omp_out+=omp_in) инициализатор(omp_priv(0,0,0)) для определения сокращения.
Я засек время только того, сколько времени потребовалось для завершения cam.render(world) с использованием std::chrono::steady_lock. При рендеринге сцены по умолчанию это дало мне ускорение всего в 1,74 раза. Однако это кажется подозрительно низким, учитывая, что я использую 8 ядер (и проверил это число с помощью omp_get_num_procs()).
Я вернулся к фиксации 2e5cc2e (только по той причине, что он был выпущен 9 декабря 2020 года, в тот же день, когда другой пользователь Github опубликовал сообщение о достижении значительного ускорения с помощью OpenMP). Я изменил код так, чтобы он записывал двумерное векторное изображение вместо вывода на стандартный вывод, а затем записывал изображение в файл. Я засчитал, сколько времени потребовалось для заполнения цвета изображения. Модифицированный код в Scene.h выглядит следующим образом:
Код: Выделить всё
std::vector image(image_height, std::vector(image_width));
omp_set_num_threads(8);
#pragma omp parallel for
for (int j = image_height-1; j >= 0; --j) {
for (int i = 0; i < image_width; ++i) {
color pixel_color(0,0,0);
for (int s = 0; s < samples_per_pixel; ++s) {
auto u = (i + random_double()) / (image_width-1);
auto v = (j + random_double()) / (image_height-1);
ray r = cam.get_ray(u, v);
pixel_color += ray_color(r, max_depth);
}
image[j][i] = pixel_color * pixel_samples_scale;
}
}
Я был компиляция с этими флагами C++: -Wall -std=c++17 -m64 -I. -fopenmp. Все файлы заголовков защищены с помощью #ifndef, поэтому нет необходимости использовать #pragma один раз вверху. Я также экспериментировал с использованием Schedule(динамический) (который кажется разумным для трассировки лучей), но это только снизило ускорение.
Дополнительную информацию по этому вопросу можно снова получить можно увидеть в недавно созданном обсуждении Github. Я считаю, что более быстрого ускорения можно легко достичь, я просто не понимаю, почему мои заголовки не обеспечивают этого.
Спасибо за любой вклад и дайте мне знать, если я могу предоставить более подробную информацию. .
Подробнее здесь: https://stackoverflow.com/questions/792 ... lelization