Comments 30
В современных FPGA слишком много ресурсов, чтобы их использовать на HDL. Поэтому лишние мы займем рантаймом C++ ;)
В runtime входит DMA контроллер, контроллер DDR, несколько AXI_INTERCONNECT (как минимум три). Это не много и соответствует обычному проекту. Но вопрос эффективности перевода С++ в HDL конечно остаётся.
Но вопрос эффективности перевода С++ в HDL конечно остаётся.
Думаю, что всё так же плохо как и раньше, как только делаешь маленький шажок в сторону от хелло-вордов типа сложения векторов.
IMHO, жизнеспособный вариант здесь только с написанием потрохов на HDL-е в комплекте с быстрым накидыванием интерфейса к хосту. А С-версию только в качестве раннего прототипа использовать.
Не так давно altera\intel провела сравнение по производительности (кажись это был gzip) между «пишем на opencl для fpga» и «берём команду матёрых hdl-щиков»(кажись они были из IBM) и сравниваем производительность. Результат — opencl реализация слила, но менее чем на 10%, а время на разработку ушло гораздо меньше.
А если сравнивать с GPU чипом производительность стала лучше?
Это требует исследований. На данный момент GPU имеют преимущество по скорости памяти. Это очень серьёзное преимущество. А также PCI Express v3.0 x16 для GPU совершенно обычное дело. Для ПЛИС в основном только x8; Кроме того GPU гораздо дешевле. Но по утверждению Xilinx вычислитель на ПЛИС имеет на порядок меньшее энергопортебление. Я тут прикинул, для среднего дата центра с потреблением 20 Мегаватт экономия на электроэнергии составит около 100 миллионов рублей в год. (а то и больше). Это перекрывает все затраты. А также это даёт возможность при том же потреблении увеличить производительность.
Сравнивать энергопотребление имеет смысл только в расчете на единицу производительности. И тут не совсем ясно, за счет чего у FPGA может быть столь значительное преимущество.
GPU имеет определённую структуру. При это всё что не используется всё равно потребляет, хотя возможно и меньше чем в рабочем режиме. ПЛИС имеет изменяемую структуру. При этом то что не используется — не потребляет
На жирной ПЛИС я могу запилить 1 ядро, или 2000 ядер. На топовом GPU я могу запилить 1 ядро, или максимум столько, сколько у этого GPU есть. На ПЛИС я могу запилить 10GbE, могу запилить 40GbE, на GPU — извините. На ПЛИС я могу поиметь QDR IV, на GPU — извините. И жрать оно может в разных конфигурация меньше, чем GPU. Опять-же, на ПЛИС я могу иметь несколько DDR/QDR/RLDRAM контроллеров, что даст мне прирост производительности в некоторых задачах.
Но вы не забывайте, что готовая микросхема/asic под заданную функцию эффективнее ПЛИС и по частоте и по потреблению.
Что-то мне подсказывает, что всяких CUDA-ядер в одном процессоре тоже сотни или тысячи…
Что-то мне подсказывает, что всяких CUDA-ядер в одном процессоре тоже сотни или тысячи…
Всё правильно, если функциональность известна, то можно сделать asic и он будет более эффективен чем ПЛИС. Но дело в том, что никто не будет делать asic под одну задачу. А ПЛИС уже есть и на ней можно экспериментировать.
В GPU TESLA K40 есть 2880 процессорных ядер. ПЛИС Kintex Ultrascale KU060 имеет 2760 DSP блоков. Хотя надо учитывать что DSP блок совершенно не одно и то же что процессорное ядро. Но для задач с фиксированной точкой это уже сравнимо. А Kintex Ultrascale KU115 имеет уже 5520 DSP блоков.
В GPU TESLA K40 есть 2880 процессорных ядер. ПЛИС Kintex Ultrascale KU060 имеет 2760 DSP блоков. Хотя надо учитывать что DSP блок совершенно не одно и то же что процессорное ядро. Но для задач с фиксированной точкой это уже сравнимо. А Kintex Ultrascale KU115 имеет уже 5520 DSP блоков.
Тут же обсуждается, как реализуются функции OpenCL на GPU kernels и FPGA kernels. Пока мне кажется, что для разных функций FPGA kernels могут тоже оказаться одинаковыми.
Ну DSP совсем не то же самое, иначе можете добавить ещё несколько тысяч ядер, реализованных на LUT-ах…
Ну DSP совсем не то же самое, иначе можете добавить ещё несколько тысяч ядер, реализованных на LUT-ах…
На примере сложения векторов уже можно увидеть что kernel для GPU и FPGA ДОЛЖНЫ БЫТЬ РАЗНЫМИ Это следует из структуры.
Для GPU: каждый kernel это сложение одного элемента, или нескольких. Для ускорения параллельно запускается много экземпляров. Счёт экземпляров идёт на тысячи.
Для FPGA: нельзя сделать много kernel. Это ограничивается числом AXI портов в компоненте AXI_INTERCONNECT. Рекомендация Xilinx — это 16 портов. Это либо 16 kernels, либо меньше если kernel имеет несколько портов. Но зато каждый kernel может легко реализовать параллельное вычисление на всех доступных ресурсах.
Для GPU: каждый kernel это сложение одного элемента, или нескольких. Для ускорения параллельно запускается много экземпляров. Счёт экземпляров идёт на тысячи.
Для FPGA: нельзя сделать много kernel. Это ограничивается числом AXI портов в компоненте AXI_INTERCONNECT. Рекомендация Xilinx — это 16 портов. Это либо 16 kernels, либо меньше если kernel имеет несколько портов. Но зато каждый kernel может легко реализовать параллельное вычисление на всех доступных ресурсах.
т.е. компилятор не будет разворачивать мой код на все доступные ресурсы? грусть печаль.
Будет. Компилятор может использовать все доступные ресурсы в пределах одного kernel.
значит я не понимаю фразу:
тупой пример сложения векторов в памяти, которая так же реализуется на FPGA, будет работать всего в 16 'потоков'?
Я думал что компилятор попытается приделать сумматор к каждому числу в этой памяти и для итогового вычисления будет все сделано за один проход/такт.
Это ограничивается числом AXI портов в компоненте AXI_INTERCONNECT. Рекомендация Xilinx — это 16 портов. Это либо 16 kernels, либо меньше если kernel имеет несколько портов.
тупой пример сложения векторов в памяти, которая так же реализуется на FPGA, будет работать всего в 16 'потоков'?
Я думал что компилятор попытается приделать сумматор к каждому числу в этой памяти и для итогового вычисления будет все сделано за один проход/такт.
Давайте рассмотрим пример сложения векторов. В заголовке статьи фото модуля ADM-PCIE-KU3; Этот модуль содержит два SODIMM 8ГБ — 1600; Внутри ПЛИС для каждого SODIMM есть свой контроллер. Шина контроллера — 512 бит.Частота 200 МГц. Скорость доступа к SODIMM около 10 Гбайт/с. Через AXI_INTERCONNECT эти два контроллера подключены к области OpenCL. Суммарная скорость обращения к памяти — около 20 Гбайт/с. Она будет разделяться между всеми клиентами. Принципиального различия в количестве kernel нет. Если будет один, то для него можно сделать два порта для двух SODIMM и получить максимальную скорость доступа к памяти. Можно сделать несколько kernel, в этом случае они будут толкаться на INTERCONNECT. Если портов будет больше 16, то накладные расходы резко возрастут, что вызовет дополнительные проблемы.
С точки зрения быстродействия, то лучше всего разместить два исходных вектора в разных SODIMM, а результат складывать тоже в разные SODIMM.При этом возможно получить скорость близкую к максимальной.
Хотя надо не забывать про PCI Express на котором 5 Гбайт/с.
На шине 512 бит будет 16 отсчётов по 32 бита. Для их сложения потребуется 16 DSP блоков. С некоторой натяжкой можно считать что обработка будет проводится в 16-ти «потоках». Так что здесь всё сводится к быстродействию памяти.
С точки зрения быстродействия, то лучше всего разместить два исходных вектора в разных SODIMM, а результат складывать тоже в разные SODIMM.При этом возможно получить скорость близкую к максимальной.
Хотя надо не забывать про PCI Express на котором 5 Гбайт/с.
На шине 512 бит будет 16 отсчётов по 32 бита. Для их сложения потребуется 16 DSP блоков. С некоторой натяжкой можно считать что обработка будет проводится в 16-ти «потоках». Так что здесь всё сводится к быстродействию памяти.
вы говорите про внешнюю память на узкой шине данных, естественно количество kernel буде ограничено пропускной способностью шины.
я спрашивал про ситуацию, когда внутренние промежуточные буферы реализуются тоже на вентилях fpga, тут же в коде opencl/verilog.
я спрашивал про ситуацию, когда внутренние промежуточные буферы реализуются тоже на вентилях fpga, тут же в коде opencl/verilog.
Промежуточные буферы будут реализованы на внутренней памяти ПЛИС. OpenCL определяет несколько вариантов, Xilinx их поддерживает.
Как бы мне от вас получить ответ на свой вопрос, а то я на самостоятельный поиск ответа убью кучу времени и сил, а он у вас уже есть.
Я пытаюсь понять, на сколько хорошо проходит генерация verilog из opencl, тем более в свете непонятного для меня ограничения в 16 'потоков'.
При использовании привычного opencl будет доступна только одна архитектура, когда память висит на шине, данные только в ней а вентили fpga только для логики?
Для задач с интенсивными вычислениями на основе данных в памяти — шина данных становится бутылочным горлышком, меня интересует, существует ли возможность в реализации оперативной памяти, где вычислительный блок находится на том же чипе, с максимально эффективным доступом к ней. Например чип paralella — 32 ядерный (64 не взлетел, и все ждут от них информации о 1024), где каждый чип имеет 64кб своей памяти и сетевую топологию подключения чипов друг к другу (каждый чип соединен только с четырьмя соседями). Представляете, какая эффективность вычислений будет на таком чипе, если данные можно будет эффективно группировать в пределах одного… пяти чипов?
Что, если аналогичное можно было бы собирать автоматически (разворачивая циклы, реорганизуя хранение данных в памяти и т.п.) на fpga? вместо тупого дублирования полноценного вычислительного ядра у каждого блока памяти, генерировать только ту логику, которая нужна для нее, да еще и перезагружать эту логику в процессе вычислений.
Как я приводил пример со сложением векторов — ячейки памяти реализуются на вентилях fpga сразу с сумматором — вычисление грубо говоря за 1 такт
Я пытаюсь понять, на сколько хорошо проходит генерация verilog из opencl, тем более в свете непонятного для меня ограничения в 16 'потоков'.
При использовании привычного opencl будет доступна только одна архитектура, когда память висит на шине, данные только в ней а вентили fpga только для логики?
Для задач с интенсивными вычислениями на основе данных в памяти — шина данных становится бутылочным горлышком, меня интересует, существует ли возможность в реализации оперативной памяти, где вычислительный блок находится на том же чипе, с максимально эффективным доступом к ней. Например чип paralella — 32 ядерный (64 не взлетел, и все ждут от них информации о 1024), где каждый чип имеет 64кб своей памяти и сетевую топологию подключения чипов друг к другу (каждый чип соединен только с четырьмя соседями). Представляете, какая эффективность вычислений будет на таком чипе, если данные можно будет эффективно группировать в пределах одного… пяти чипов?
Что, если аналогичное можно было бы собирать автоматически (разворачивая циклы, реорганизуя хранение данных в памяти и т.п.) на fpga? вместо тупого дублирования полноценного вычислительного ядра у каждого блока памяти, генерировать только ту логику, которая нужна для нее, да еще и перезагружать эту логику в процессе вычислений.
Как я приводил пример со сложением векторов — ячейки памяти реализуются на вентилях fpga сразу с сумматором — вычисление грубо говоря за 1 такт
Вопрос — насколько хорошо будет получаться проект ПЛИС из описания на С++ сейчас волнует очень многих. Я пока не могу на это дать ответ. Это требует дальнейшего изучения.
Другой вопрос — как ПЛИС подходит для интенсивных вычислений. Конечно подходит. И так как нет жёсткой структуры то возможны разнообразные варианты.
Например при реализации БПФ есть вычислительный блок — бабочка. Он связан с другой бабочкой и т.д. Получается полностью конвейерная структура. С очень интенсивными вычислениями. Пример — в статье capitanov Реализация узла БПФ с плавающей точкой на ПЛИС Этот БПФ написан на VHDL. Я в принципе собираюсь его подключить как OpenCL kernel, но это будет RTL kernel.
При описании на С++ также возможно делать подобные вычислительные структуры. Мы можем описать массив и указать что он находится во внутренней памяти ПЛИС. И над ним производить разнообразные вычисления. Есть различные методы оптимизации, в том числе разворачивание циклов. Можно сказать, что в ПЛИС вычислительные структуры максимально приближены к памяти.
Кстати есть ещё одна очень интересная штука, называется Hybrid Memory Cube. Это память с подключением по четырём независимыми линкам. Объём памяти 2 или 4 Гбайт. Так вот, четыре линка позволяют использовать память как коммутатор. А ещё она может выполнять некоторые вычисления.
Другой вопрос — как ПЛИС подходит для интенсивных вычислений. Конечно подходит. И так как нет жёсткой структуры то возможны разнообразные варианты.
Например при реализации БПФ есть вычислительный блок — бабочка. Он связан с другой бабочкой и т.д. Получается полностью конвейерная структура. С очень интенсивными вычислениями. Пример — в статье capitanov Реализация узла БПФ с плавающей точкой на ПЛИС Этот БПФ написан на VHDL. Я в принципе собираюсь его подключить как OpenCL kernel, но это будет RTL kernel.
При описании на С++ также возможно делать подобные вычислительные структуры. Мы можем описать массив и указать что он находится во внутренней памяти ПЛИС. И над ним производить разнообразные вычисления. Есть различные методы оптимизации, в том числе разворачивание циклов. Можно сказать, что в ПЛИС вычислительные структуры максимально приближены к памяти.
Кстати есть ещё одна очень интересная штука, называется Hybrid Memory Cube. Это память с подключением по четырём независимыми линкам. Объём памяти 2 или 4 Гбайт. Так вот, четыре линка позволяют использовать память как коммутатор. А ещё она может выполнять некоторые вычисления.
Только все подробности про эту HMC память под NDA для больших фирм.
очень грустное ценообразование, $3k за pcie модуль, подешевле будут модули для камер, $750…
нужна, нужна очень грамотная конкуренция видеоускорителям на рынке числодробилок.
нужна, нужна очень грамотная конкуренция видеоускорителям на рынке числодробилок.
А можно ли сначала написать kernel на kernel C, а потом допилить на верилоге? Например, если я хочу туда добавить что-то экзотическое, типа восьмибитной плавающей точки.
Т.е. это по сути объединение универсальных ядер, поддерживающих openCL и исполняемый код отдельно или реализация только определённых заранее заданных последовательностей функций openCL в чистый hdl?
Существует три способа написания kernel
1. Стандарт OpenCL
2. C++ — используется Vivado HLS со всеми возможностями оптимизации
3. RTL — на языках VHDL/Verilog.
Естественно, если идёт разработка на VHDL/Verilog, то в него можно вставлять компоненты на Vivado HLS.
Для варианта RTL в итоге получается компонент, которому стандартным образом передаются параметры и который запускается стандартной командой из программы HOST. Также есть стандартный механизм информирования о завершении работы. А всё остальное — определяется фантазией и возможностями разработчика.
1. Стандарт OpenCL
2. C++ — используется Vivado HLS со всеми возможностями оптимизации
3. RTL — на языках VHDL/Verilog.
Естественно, если идёт разработка на VHDL/Verilog, то в него можно вставлять компоненты на Vivado HLS.
Для варианта RTL в итоге получается компонент, которому стандартным образом передаются параметры и который запускается стандартной командой из программы HOST. Также есть стандартный механизм информирования о завершении работы. А всё остальное — определяется фантазией и возможностями разработчика.
Для варианта RTL в итоге получается компонент, которому стандартным образом передаются параметры и который запускается стандартной командой из программы HOST. Также есть стандартный механизм информирования о завершении работы. А всё остальное — определяется фантазией и возможностями разработчика.
Хороший вариант, особенно в комплекте с возможностью проработать алгоритмическую часть на 1-м или 2-м варианте.
P.S. Извините, не в ту ветку уехало.
Sign up to leave a comment.
SDAccel – первое знакомство