Дмитpий Hecтepук

Блог о программировании — C#, F#, C++, архитектура, и многое другое

Posts Tagged ‘hardware parallelism

Ключевые особенности FPGA

2 комментария

Многие из вас наверное видели, что Amazon запускает инстансы EC2 с FPGA на борту. Я сразу признаюсь, что я никогда не пользовался облаками Amazon: я использую только Azure, и то только потому что мне некоторый объем вычислительным мощностей дают бесплатно как MVP (которым я являюсь уже ажъ 8 лет!), а до этого у меня просто стоял свой собственный сервер в универе, про который мало кто знал пока через одно веб-приложение (MindTouch Core, если кому интересно) на сервере кто-то установил спамбота, и понеслась.

Короче, я не юзаю Амазон облако, да и в последнее время стараюсь поменьше заказывать с Амазона: сейчас ведь там продают очень многие ритейлеры, у которых есть свои сайты, соответственно я скорее куплю за ту же стоимость у них, чтобы им перепало побольше, а Амазону — нуль. Думаю причины сего поведения с моей стороны вы итак прекрасно понимаете — Амазон прекрасен для покупателя (хотя скорость доставки в Англии упала до неприличия), но вот к программистам они, судя по “среднему по больнице”, относятся как к шлаку. И да, понятно что есть продуктовые команды в которых все нормально, но судя по тому что пишут на Reddit, общее положение все же весьма бредовое. Если вы там работаете, можете меня поправить и рассказать как все шикарно.

Ах, да, тьфу ты, я на самом деле немного некорректно тут написал. Основная проблема моя с Амазоном не в этом, а в том что они не берут PayPal. Это как бы критично т.к. на мелкие покупки я трачу только свой disposable income, а он у меня весь на PayPal.

Че-то я отъехал от темы. Вроде пост был про FPGA.

Концепция dataflow

У нас есть много разных плохо коммутируемых парадигм разработки – например процедурная, объектно-ориентированная, функциональная. А есть парадигма, которую можно называть “потоковой”, а по-английски она называется словом dataflow.

Идея dataflow тривиальна как в танке: представьте, что входные данные в системе проходят через некий map-reduce, т.е. обработку потока этих данных с некоторыми критериями выборки. Например на вход могут прийти три числа и нужна их сумма, то есть

int sum(int a, int b, int c)
{
  return a + b + c;
}

Возникает вопрос: сколько времени занимает код выше? Если мыслить о том что написано выше в терминах C++, C#, Java или аналогичных языков, то код — то есть набор инструкций — будет транслирован в несколько вызовов add, и соответствено займет ненулевое время на выполнение.

Сколько займет тот же самый алгоритм на FPGA? Ну, если утрировать до боли, но он займет нуль времени. Сигналы a, b и c будут поданы на соответствующие схемы, который в момент на выходе выдадут результат. Никаких “инструкций” не произойдет.

Понимание того, что программрование FPGA — это конфигурирование интегральной микросхемы (я тут возможно путаю терминологию, поправьте если что), а не описание набора инструкций — это ключ к пониманию того, что собственно можно выудить из технологии FPGA и к каким она задачам применима. Сейчас мы как бы понимаем, что когда по проводам идут данные с бешеной скоростью (например, интернет на 10G), обычный CPU — даже самый навороченный Xeon — не сможет эти данные переварить содержательно, разбирая, например, коммуникационный протокол по которому идут биржевые данные. Но это только часть задачи.

Аппаратный параллелизм

Современный процессор, безусловно, поддерживает некоторый уровень параллелизма: у нас есть “многоядерность”, у нас есть т.к. hyper-threading, ну и конечно у нас есть SIMD, который помошает делать больше вычислений за счет больших регистров. Но, так или иначе, этот паралеллизм заранее лимитирован процессором: мы знаем, например, что на Xeon Phi (60 ядер по 4 аппаратных потока каждое) не имеет особого смысла запускать более 240 потоков и, более того, на обычных CPU мы не контролируем, какая задача ложится на какой поток: это обычно делает операционная система (в случае с Xeon Phi там используется свой собственный Linux).

Ситуация с FPGA несколько другая: там за один такт можно делать совершенно несвязанные операции, и количество таких операций лимитировано только количеством логических элементов на кристалле. Иначе говоря, FPGA способствуют такому масштабу параллелизма, о котором с обычными CPU остается только мечтать.

Это не значит, что FPGA дает самый лучший performance. У нас есть очень мощные модели параллелизма (например SIMT на GPU) с которыми FPGA не может бодаться в плане обработки больших объемов данных. Но и цель у FPGA немножко не такая: ведь на GPU каждый поток должен делать одно и то же (иначе теряется вся эффективность), а FPGA может на разных своих участках делать абсолютно разные вещи. Синхронизация между этими участками — это достаточно сложная задача, конечно, но with great power… ну вы поняли.

Да, еще один аспект, который нужно упомянуть — это тактовая частота. На CPU тактовая частота одна, и все задачи синхронизуются на нее. На FPGA вы можете использовать разные генераторы (по английски clock), т.е. сигналы разной частоты для разных задач. Тактовая частота FPGA в целом существенно уступает CPU, но сравнивать их напрямую не особенно интересно, т.к. они служат разным целям.

Концепция pipelining

Я не буду скрывать, что и на обычных Intel’евских CPU происходит много всякой магии вроде branch prediction. По сути, современный ассемблерный код, который выдает вам С++ компилятор с включенными оптимизациями, читать достаточно сложно про причине того, что количество “магии”, которое обычно вкладывается в погони за перформансом, огромно. Ассемблер можно читать разве что в идеальном мире, без оптимизаций.

Pipelining объяснить просто. Возьмем следующий код:

void mad(int* a, int* b, int* c, int* result size_t count)
{
  for (size_t i = 0; i < count; ++i)
    result[i] = a[i]*b[i] + c[i];
}

Вы наверное думаете что каждая итерация цикла for должна закончиться прежде, чем начнется новая. В контексте С++ вы правы, а в контексте FPGA — нет!

Представьте операцию a*b+c как микросхему, работающую под определенной тактовой частотой: на первый шаг, вы подаеет значения a и b и получаете их произведение. Потом надо бы прибавить c, а что в это время делает та часть которая умонжает. Думаете она простаивает и ждет пока завершится вычисление? А вот и нет! Эта часть схемы может брать и считать следующее произведение, т.е. a*b для следующей пары чисел a и b.

Вот это и называется pipelining: возможность сразу пропускать целый поток значений, не дожидаясь завершения всего вычисления. И, как вы надеюсь уже догадались, это приводить к существенному ускорению, т.к. является de facto еще одним уровнем аппаратного параллелизма.

Что такое SoC

SoC расшифровывется как System-on-a-Chip, и в контекте она подразумевает некую аггломерацию FPGA с обычными процессорами вроде ARMов. При этом эти процессоры не просто “сосуществуют на плате”, а ARM встроен прямо в FPGA.

А вот это уже интересно, т.к. на ARM мы просто ставим свою собственную ось (вопрос про то, можно ли туда поставить Windows остается открытым, т.к. MS как-то протормаживают в этом плане), и тем самым получаем на одном кристалле, по сути, полноценно-работающий компьютер — нужно только добавить оперативки и периферию (например PCIe, Ethernet, …) по вкусу. Собственно это должно объяснять почему это “system on a chip” — на одном кристалле все, что нужно чтобы выполнять какую-то экспертную задачу.

Покупка Intel’ем компании Altera, второго по размеру производителя FPGA, намекает на симметричное развитие Xeon’ов: идея в том чтобы воткнуть в процессор какой-нть FPGA и дать разработчикам программировать его и осуществлять взаимодействие между CPU и FPGA вместо того чтобы ходить по PCIe шине, как предлагает Amazon.

Кстати, покупка Altera может выйти сильным боком Российским производителям (в т.ч. ВПК и тем кто под санкциям). Причина проста — сейчас, Altera и в частности ее дистрибьютор Terasic — это коррумпированая Тайваньская лавочка, которая вышлет что угодно и куда угодно, в то время как лидер рынка, Xilinx, каждую закупку пропускает через DoD на предмет санкций, dual use и так далее. Если Intel начнет себя вести так же, настанут очень веселые времена. Или вы думаете что в РФ у кого-то есть производственные мощности для импотрозамещения? Ну-ну.

Высокоуровневый синтез

HLS (high-level synthesis) — это не что иное, как кодогенерация VHDL/Verilog из более популярных языков вроде С++ и SystemC. Последний — этот тот же С++, как мне видится, только с некоторым набором конструктов для системного мира (например fixed-point types).

HLS подходов очень много, и объединяет их то, что все они генерируют очень сложную к прочтению и пониманию кашу, которую уже некомфортно читать. Помимо этого, наивно полагать что вы можете взять уже существующий С++ и просто нажать кнопочку “сделать мне хорошо” — вы не можете так просто поменять процедурную парадигму на поточную. Возможность писать что-то новое на С++ дает, разве что, варианты портирования этого “что-то” на x86 и иже с ним, но опять же, непонятно что это дает — разве что тестировать это можно быстрее, да и в Cling-е гонять.

Лично я склонен думать, что у HLS будущее, и что HDL’и должны отмереть за их чрезмерной низкоуровневостью. Но пока что, они — лучший способ описать, что и как должно произходить в системе. ■

Written by Dmitri

11 декабря 2016 at 22:00

Опубликовано в FPGA

Tagged with , , ,