Является ли обработка большого трехмерного массива от 100 до 100 инструкций на строку массива хорошей проблемой, которую нужно решить на GPU? - PullRequest
0 голосов
/ 18 июня 2020

У меня проблема, когда мне нужно запустить сложную функцию на большом трехмерном массиве. Для каждой строки массива я выполню от 100 до 1000 инструкций, и в зависимости от данных в этой строке некоторые инструкции будут выполнены или нет.

Этот массив большой, но он все равно помещается в разделяемую память графического процессора (размером около 2 ГБ). Я мог бы выполнить эти инструкции для отдельных частей массива, учитывая, что их не нужно обрабатывать по порядку, поэтому я думаю, что выполнение на графическом процессоре может быть хорошим вариантом. Я не совсем уверен, потому что выполняемые инструкции будут меняться в зависимости от самих данных (там много if / then / else), и я читал, что ветвление может вызвать проблему.

Эти инструкции являются абстрактным синтаксисом дерево, представляющее короткую программу, которая работает над строкой массива и возвращает значение.

Похоже ли это на подходящую проблему, которую должен решить GPU?

Какая еще информация потребуется для определения это?

Думаю написать это в Java и использовать JCuda.

Спасибо!

Eduardo

1 Ответ

1 голос
/ 30 июня 2020

Это зависит. Насколько велик ваш массив, т.е. сколько параллельных задач предоставляет ваш массив (в вашем случае это звучит так, как будто количество строк - это количество параллельных задач, которые вы собираетесь выполнить)? Если у вас мало строк (AST), но много столбцов (команд), то, возможно, это того не стоит. Лучше было бы работать наоборот, потому что можно распараллелить больше работы.

Ветвление действительно может быть проблемой, если вы не знаете. Вы можете сделать некоторые оптимизации, чтобы уменьшить эту стоимость - после того, как вы запустили свой первоначальный прототип и можете провести некоторые измерения для сравнения. та же инструкция. Если одному ядру эта инструкция не нужна, оно спит. Таким образом, если у вас есть два AST, каждый со 100 различными командами, мультипроцессоры будут принимать 200 команд для завершения расчета, некоторые SM будут спать, а другие будут выполнять свои команды.

Если у вас есть максимум 1000 команд а некоторые используют только подмножество, процессор будет принимать столько команд, сколько AST с наибольшим количеством команд - в оптимальном случае. Например, набор (100, 240, 320, 1, 990) будет выполняться как минимум для 990 команд, даже если один из AST использует только одну команду. И если этой команды нет в наборе из 990 команд из последнего AST, она выполняется даже для 991 команды.

Вы можете смягчить это (после того, как прототип заработает и сможете проводить фактические измерения) путем оптимизации массив, который вы отправляете в графический процессор, так что один набор потоковых мультипроцессоров (блок) имеет аналогичный набор инструкций. Поскольку разные SM не мешают друг другу на уровне исполнения, им не нужно ждать друг друга. Размер блоков также настраивается при выполнении кода, поэтому вы можете немного изменить его здесь.

Для еще большей оптимизации - только 32 (NVidia "Warp") / 64 (AMD "Wavefront") из потоки в блоке выполняются одновременно, поэтому, если вы организуете свой массив для использования этого, вы даже можете получить немного больше.

Насколько важны эти оптимизации, зависит от того, насколько разреженные / плотный / смешанный ваш командный массив будет. Также не все оптимизации действительно оптимизируют время выполнения. Ключевым моментом здесь является тестирование и сравнение. Еще один источник оптимизации - это макет вашей памяти, но с описанным вами вариантом использования это не должно быть проблемой. Вы можете посмотреть Объединение памяти для получения дополнительной информации об этом.

...