2012-03-09 1 views
0

Я разрабатываю трассировщик лучей Монте-Карло в OpenCl для вычисления «коэффициентов просмотра» для анализа радиационной теплопередачи и хочу знать оптимальный способ сопоставления количества объектов времени x пересекается лучами, возбуждаемыми из объекта i.Оптимальный способ записи данных пересечения лучей для трассировки лучей с использованием OpenCL

В настоящее время основной алгоритм выглядит следующим образом:

  1. Огня случайного луч, R, от поверхности объекта я
  2. Теста пересечения луча R с объектами 0 - Н
  3. Определить первый объект пересекается R, пусть это будет объект х
  4. Запись первое пересечение приращением массив такого этого массива Int в [I] [X] + = 1
  5. Повтор для общего количества лучей
  6. Разделите каждое значение в i-й строке массива на общее количество массивов, запущенных из объекта i.

Теперь, как правило, в параллельной реализации на процессоре каждый поток будет просто содержать свою собственную копию массива [N], а затем, когда все лучи будут запущены из объекта i, главный поток будет суммировать отдельные массивы, чтобы получить результаты.

В OpenCL на GPU это не практическое решение, так как при увеличении N быстро становится нехваткой локальной памяти, и использование одного массива с барьерами будет приводить к ухудшению производительности.

Что лучше всего подходит для преформирования результирующего массива результатов или является барьером памяти, единственным практическим решением?

ответ

0

Kernel A) Делайте это, как вы описали, записывая свои собственные копии массива [N] обратно в глобальную память в конце.

Kernel B) Ядро для редукции (что «основной поток» делает в вашем описании).

Сделать все вызовы ядра. Установить события по завершении. Сделать вызовы (я) ядра B зависят от этих событий. Вы даже можете использовать несколько вызовов ядра B для сокращения пирамиды, используя две (или более, настраиваемые) массивы и выписывая одну сумму. Цепь событий может разрешать зависимости и допускать глубокую очередность.

+0

Вы говорите, что ядро ​​A должно содержать копию на рабочую группу в локальной памяти копии на элемент обработки в частной памяти? – cubiclewar

+0

Возможно ли в вашей реализации запросить размер локальной памяти, а затем каждый вызов ядра вычисляет диапазон значений этих (локальных) массивов [N]? В конце ядра скопируйте этот локальный массив [N] обратно в глобальные буферы и запустите некоторое количество ядро ​​Б, чтобы выполнить их сокращение. – doug65536