|
|
  |
Подскажите по оптимизации, нужно выжать максимум |
|
|
|
Mar 23 2015, 20:59
|
Группа: Участник
Сообщений: 12
Регистрация: 5-01-07
Пользователь №: 24 120

|
Дано: Virtex-6 XC6VLX240T Центральный модуль, включающий себя UART и подготовку данных. Есть вычислительные модули, которые коннектятся к центральному, их интерфейс: Код ( clock : in std_logic; reset : in std_logic; data_input : in std_logic_vector(31 downto 0); data_flag : in std_logic;
done : out std_logic; data_ready : out std_logic ) С точки зрения использования ресурсов в плис влезает около 230 таких модулей + центральный. При 64 модулях все это хорошо живет на 200Мгц, данная частота и является целью. При 128 модулях синтезатор уже выдаёт максимальную частоту 140MHz, что не устраивает. Причем, PlanAhead показывает, что критические пути - это линии соединения вычислительных модулей с центральным. Попробовал добавить регистры в эти линии: Код signal reset_corebuf : std_logic_vector(NCORES - 1 downto 0); signal data_input_corebuf : std_logic_vector((NCORES * 32) - 1 downto 0); signal data_flag_corebuf : std_logic_vector(NCORES - 1 downto 0); signal done_corebuf : std_logic_vector(NCORES - 1 downto 0); signal data_ready_corebuf : std_logic_vector(NCORES - 1 downto 0);
process (clk) begin if (rising_edge(clk)) then for i in 0 to NCORES - 1 loop reset_corebuf(i) <= reset; data_input_corebuf((i + 1) * 32 - 1 downto i * 32) <= core_data; data_flag_corebuf(i) <= data_core_flag(i); core_done(i) <= done_corebuf(i); data_core_ready(i) <= data_ready_corebuf(i); end loop; end if; end process; И вот эти промежуточные сигналы уже законнектил к вычислительным модулям. Лучше не стало, хотя по логике - должно. Подскажите пожалуйста, что я делаю не так и куда копать)
Сообщение отредактировал v1vas - Mar 23 2015, 21:04
|
|
|
|
|
Mar 24 2015, 07:24
|
Знающий
   
Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515

|
Цитата(v1vas @ Mar 23 2015, 23:59)  И вот эти промежуточные сигналы уже законнектил к вычислительным модулям. Лучше не стало, хотя по логике - должно. Подскажите пожалуйста, что я делаю не так и куда копать) При ручной репликации регистров на все реплицированные сигналы надо повесить атрибут syn_preserve, иначе синтезатор их может оптимизировать в один регистр, из-за чего у вас, вероятно, и не стало лучше. Кроме того, 230*35 - это 8000 независимых длинных линий, которые будут зря жрать электричество и могут переполнить ресурсы интерконнекта. Лучше создать древовидную структуру, например, 16 регистровых групп к центральному блоку, и 8-16 оконечных устройств на каждую регистровую группу.
|
|
|
|
|
Mar 24 2015, 14:16
|
Гуру
     
Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369

|
Цитата(v1vas @ Mar 23 2015, 23:59)  Дано: Virtex-6 XC6VLX240T Центральный модуль, включающий себя UART и подготовку данных.
С точки зрения использования ресурсов в плис влезает около 230 таких модулей + центральный.
Подскажите пожалуйста, что я делаю не так и куда копать) Если не вдаваться в детали, то дело выглядит удивительно... Есть один медленный UART и не понятно кто делает протокол передачи байтов в хост. Дальше еще удивительней. 230 модулей должны работать ОДНОВРЕМЕННО??? Тогда сколько же длится "Обработка в модуле", если ее результат передается не понятно по какому протоколу через медленный UART. Почему-то мне кажется, что если сделать многопоточную обработку одним модулем да еще и на 200Мгц, то он вполне справится за то время, пока UART передает-получает данные в хост. Ну, если уж не один модуль, то десятка вполне хватит... И при таком подходе обнаружится, что кристалл будет заполнен на 10%...
--------------------
www.iosifk.narod.ru
|
|
|
|
|
Mar 24 2015, 17:42
|
Группа: Участник
Сообщений: 12
Регистрация: 5-01-07
Пользователь №: 24 120

|
Давайте вдаваться в детали, чтобы все не выглядело так ужасно, как это понял iosifk =) Есть вычислительный модуль, в нем достаточно легковесная математика. Он единоразово принимает 34 байта стартовых данных и далее на протяжении примерно 5 500 000 000 шагов (1 шаг - 1 такт) эти данные обрабатывает. При частоте 200МГц - это около 30 секунд. В процессе этих 30 секунд никакие данные модулю больше не нужны. По итогам работы модуля мы на выходе получаем один бит: вычислилось ли интересующее нас значение или нет (флаг data_ready в первом интерфейсе, что я написал). Это происходит в среднем только один раз на 300 000 вариантов входных данных, поэтому мне достаточно просто знать для каких данных это произошло, а все остальное я проверяю на хосте. Ну и соответственно есть флаг done, когда все модули закончили - я им бросаю следующую пачку данных, предварительно принятых по UART, а обратно отправляю номер модуля который что-то вычислил, если он есть. UART - другой частотный домен, заведен на два FIFO - один для отправки данных, один для приемки. Главный модуль: объединяет и контролирует всё это. Общая структура и порядок работы главного модуля: 1) Проверяем FIFO, в котором скапливаются данные прилетевшие с хоста, для каждых 34 байт оказавшихся там - отправляем их в вычислительный модуль. 2) Когда загрузили все модули - ждем, пока все модули посчитают (у всех done = '1') 3) Если у какого-то модуля data_ready = '1' - кидаем номер этого модуля в FIFO для отправки данных на хост 4) Ресетим модули и идем на пункт один Вычислительный модуль: 1) Если data_flag = '1', то в data_input лежат валидные данные. 2) Как накопили 34 байта - начали работу. 3) Если вычислилось то, что нужно data_ready <= '1'; 4) Как закончили done <= '1'; Изначально вычислительные коннектились к основному прозаично: Код MTMainCores: for i in 0 to NCORES - 1 generate begin CoreEntry: CRMain GENERIC MAP ( CORE_N => i ) PORT MAP ( clock => clk, reset => reset, data_input => core_data, data_flag => data_core_flag(i), done => core_done(i), data_ready => data_mt_ready(i) ); end generate MainCores; Потом добавил регистры, про которые написал в первом сообщении. По совету Timmy добавил им аттрибут "keep": Код attribute keep : string; attribute keep of reset_corebuf: signal is "true"; attribute keep of data_input_corebuf: signal is "true"; attribute keep of data_flag_corebuf: signal is "true"; attribute keep of done_corebuf: signal is "true"; attribute keep of data_ready_corebuf: signal is "true"; И на текущий момент имею 48084 timing score для 128 модулей и вот такой критический путь: Код Paths for end point Mmux__n4665412_FRB (SLICE_X98Y138.D3), 312 paths -------------------------------------------------------------------------------- Slack (setup path): -2.621ns (requirement - (data path - clock path skew + uncertainty)) Source: MTMainCores[3].CoreEntry/data_ready_BRB2 (FF) Destination: Mmux__n4665412_FRB (FF) Requirement: 5.000ns Data Path Delay: 7.486ns (Levels of Logic = 5) Clock Path Skew: -0.100ns (1.521 - 1.621) Source Clock: clk_BUFGP rising at 0.000ns Destination Clock: clk_BUFGP rising at 5.000ns Clock Uncertainty: 0.035ns Clock Uncertainty: 0.035ns ((TSJ^2 + TIJ^2)^1/2 + DJ) / 2 + PE Total System Jitter (TSJ): 0.070ns Total Input Jitter (TIJ): 0.000ns Discrete Jitter (DJ): 0.000ns Phase Error (PE): 0.000ns Maximum Data Path at Slow Process Corner: MTMainCores[3].CoreEntry/data_ready_BRB2 to Mmux__n4665412_FRB Location Delay type Delay(ns) Physical Resource Logical Resource(s) ------------------------------------------------- ------------------- SLICE_X70Y134.DQ Tcko 0.337 MTMainCores[3].CoreEntry/data_ready_BRB2 MTMainCores[3].CoreEntry/data_ready_BRB2 SLICE_X70Y132.C1 net (fanout=1) 0.710 MTMainCores[3].CoreEntry/data_ready_BRB2 SLICE_X70Y132.C Tilo 0.068 data_mt_ready<3> MTMainCores[3].CoreEntry/data_ready_rstpot SLICE_X97Y70.B3 net (fanout=5) 2.967 data_ready_corebuf<3> SLICE_X97Y70.B Tilo 0.068 data_mt_ready<7> Mmux__n466542 SLICE_X98Y112.D6 net (fanout=1) 1.627 N19372 SLICE_X98Y112.D Tilo 0.068 MTMainCores[21].CoreEntry/SM_STATE_FSM_FFd4_BRB1 Mmux__n466544 SLICE_X98Y138.C5 net (fanout=1) 1.158 N19376 SLICE_X98Y138.C Tilo 0.068 Mmux__n4665412_FRB N19384 SLICE_X98Y138.D3 net (fanout=1) 0.345 N19384 SLICE_X98Y138.CLK Tas 0.070 Mmux__n4665412_FRB Mmux__n4665412 Mmux__n4665412_FRB ------------------------------------------------- --------------------------- Total 7.486ns (0.679ns logic, 6.807ns route) (9.1% logic, 90.9% route)
|
|
|
|
|
Mar 24 2015, 18:24
|
Вечный ламер
     
Группа: Модераторы
Сообщений: 7 248
Регистрация: 18-03-05
Из: Томск
Пользователь №: 3 453

|
Цитата(v1vas @ Mar 25 2015, 01:42)  Общая структура и порядок работы главного модуля: 1) Проверяем FIFO, в котором скапливаются данные прилетевшие с хоста, для каждых 34 байт оказавшихся там - отправляем их в вычислительный модуль. 2) Когда загрузили все модули - ждем, пока все модули посчитают (у всех done = '1') 3) Если у какого-то модуля data_ready = '1' - кидаем номер этого модуля в FIFO для отправки данных на хост 4) Ресетим модули и идем на пункт один
Вычислительный модуль: 1) Если data_flag = '1', то в data_input лежат валидные данные. 2) Как накопили 34 байта - начали работу. 3) Если вычислилось то, что нужно data_ready <= '1'; 4) Как закончили done <= '1'; понятно, майнер делаете. Интерфейс ваших данных 34 байта и интерфейс результата перенесите в домен низкой частоты UART (CDC поставьте в вычислительные движки), саму шину на запись сделайте что-то вроде вишбона, на чтение соберите все с большой сдвиговый регистр и результат на хост. Ну и констрейны правильные натравить. И все заробит. ЗЫ. схему бы нарисовали себе, все стало бы как на ладони. У меня бойцы в добровольно-принудительном порядке такое делают.
--------------------
|
|
|
|
|
Mar 24 2015, 19:32
|
Группа: Участник
Сообщений: 12
Регистрация: 5-01-07
Пользователь №: 24 120

|
Это не майнер, это очень специфичный брут-форс для очень экзотичной задачи) Но архитектурно идеи те же, согласен.
Схему держу в голове, объёма мозга хватает. Но перенесу на бумагу, хорошо, заодно и здесь выложу.
За советы спасибо! Начну воплощать.
Сообщение отредактировал v1vas - Mar 24 2015, 19:33
|
|
|
|
|
Apr 3 2015, 11:58
|
Частый гость
 
Группа: Свой
Сообщений: 139
Регистрация: 3-04-13
Пользователь №: 76 333

|
Цитата(v1vas @ Mar 24 2015, 22:32)  Это не майнер, это очень специфичный брут-форс для очень экзотичной задачи) это что же за брутфорс такой, для реализации которого понадобилось фигачить проект на fpga ))?
|
|
|
|
|
Apr 3 2015, 12:05
|
Гуру
     
Группа: Модераторы
Сообщений: 4 011
Регистрация: 8-09-05
Из: спб
Пользователь №: 8 369

|
Цитата(v1vas @ Mar 24 2015, 20:42)  Давайте вдаваться в детали, чтобы все не выглядело так ужасно, как это понял iosifk =)
Есть вычислительный модуль, в нем достаточно легковесная математика. Он единоразово принимает 34 байта стартовых данных и далее на протяжении примерно 5 500 000 000 шагов (1 шаг - 1 такт) эти данные обрабатывает. При частоте 200МГц - это около 30 секунд. В процессе этих 30 секунд никакие данные модулю больше не нужны.
Причем, PlanAhead показывает, что критические пути - это линии соединения вычислительных модулей с центральным. Вот , о чем я и написал... Плохой подход гонять параллельные шины и делать все "в лоб". Сделайте так: В центральный модуль добавье что-то вроде SPI, который будет передавать-принимать из вычислителей данные в последовательном коде. При 30 сек добавить еще несколько тактов на 34 бита - думаю что это проблемой не будет...
--------------------
www.iosifk.narod.ru
|
|
|
|
|
Apr 7 2015, 19:48
|
Знающий
   
Группа: Свой
Сообщений: 654
Регистрация: 24-01-07
Из: Воронеж
Пользователь №: 24 737

|
Передача через входную шину идёт редко. Дёргайте data_flag не каждый такт, а раз в три такта плюс set_multicycle_path. PS. Брутфорс экономичнее делать на более мелких ПЛИС как вот эти.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|