Все время забываю про ИИ. Он пишет, что 4К бпф 66-й делает за 26000-29000 тактов при самом лучшем расположении данных. Но меня больше сразила цифра тактов для 16К - 328000. Или 131000 если использовать реализацию на все ядра. Но , конечно, веры в эти цифры нет :)
Когда-то я работал с DSP К1967ВН44. Для ориентира , у него БПФ с такими же числами для 4К- 23420 тактов, 16К - 117930, 64К-635000. Судя по всему у Вас еще не самый лучший результат получился.
Помню, в 97-м прошлого века в КБ при заводе сделали НИР и получили рабочий чип. Затем я увидел ТЗ на ОКР с окончанием в 2013. Я думал, что шутка. Но в 2013 чип реально появился. А Вы говорите 7.5 месяцев. Это если за Вас кто-то все уже сделал :)
Вы , как и я, еще не привыкли к ИИ :) Если задать ему Ваш вопрос по поводу популярности в прошлые годы, то одной из фраз будет такая:" По данным на 2018 год, около 80% проектных групп в мире использовали Verilog или SystemVerilog. "
Вот над этим хорошо бы акцентировать внимание. Когда-то я делал ASIC для автомобильного ключа на 8-разрядном МК: ядро+SRAM+ flash+простой последовательный интерфейс. Нажимаем кнопку - подается питание, МК читает из флэша число, шифрует его , отправляет, записывает во флэш новое число и отключается. Какое ядро из этих двух лучше подойдет для такого применения? Требования - чтобы батарейка работала как можно дольше и чип был как можно дешевле.
Этот тест был бы информативнее, но на мой взгляд, в статье нужно было немножко больше рассказать об особенностях исполнения команд в PicoRV32. Суть в том, что у него нет никакого конвейера и если вы выставите наилучшие условия для быстрой работы, то даже NOP команда будет исполняться за 3 такта. Если память работает не идеально, т.е. запрос на чтение команды в текущем такте, а сама команда в следующем такте, то уже как минимум 4 такта на любую команду. Поэтому нужно ожидать , что по тактам Picorv32 будет в 4 раза проигрывать SCR1 на одинаковом коде. Если используется С расширение, то иногда команда уже выбрана и тогда для неё 3 такта. Итого ухудшение по тактам будет меньше 4-х. Сравнивать эти ядра как-то даже не интересно если есть мысли о каком-то быстродействии.
я посмотрел времянку SCR1 на этом тесте. Скажу так - тест выбран очень неудачно. Сами представьте: всего 453 такта на итерацию в которой только одна операция умножения. Поэтому и выводы такие, что лучше выбирать минимальную конфигурацию SCR1 (без умножения) т.к. она не уступает максимальной (с аппаратным однотактным умножителем). Все верно, но только для этого теста. Попробуйте другой тест.
Спасибо за уточнение. Поспрашивал ИИ :) Действительно, для экономии и упрощения всего и вся, следующая команда потока не запускается на конвейере пока не завершится предыдущая. ВЫгодно запускать число потоков не меньшее длины конвейера.
Напоминает многоядерную систему с общей памятью, в которой арбитр доступа к памяти перенесен в ядро процессора :) Интересно было бы сравнить 8-миядерный однопоточный с одноядерным 8-мипоточным по площади и частоте. Судя по реализации XCORE одному потоку гарантируется 1/8 времени минимум. Хотя при этом нужно еще уметь исполнять первый поток когда второй остановился. Итого чтобы один поток имел 100 МГц , вся система должна работать на 800 МГц. Решение прикольное.
У меня каждый вечер сверху как будто телега по потолку катается. Это такой же пылесос? А еще как будто стиралка работает . Может это он так заряжается? Надоело конкретно.
Когда-то программировал под ARM и там как раз такое решение - располагать константы в дырках между функциями. Но в данном случае компилятор не пользуется таким приемом, а кладет константу только за кодом.
Да. Код у меня расположен , начиная с 0-го адреса. Секция данных сразу за кодом. Размер кода при -О0 1244 байта, при -О2 1246 байт. Я специально для -О2 вырезал часть кода из ассемблерного стартапа , но компилятор не поменял решения.
LUI+ADDI это типовая склейка в одну команду у RISC-V. Вы правы в предположении.Загрузка константы в простом суперскалере на 2 команды за такт займет максимум 4 такта. Иногда компилятор делает LUI+ADDI не перемешивая. А в конце сдвиг и сложение. Теоретически сдвиг на 32 и сложение тоже можно склеить. Не знаю делают ли так, но в этом случае 3 такта.
Чтобы понять какой вариант быстрее нужен не только тест, но еще нужно выбирать и конкретную реализацию процессора. У меня такое впечатление , что компилятор отлаживают на каком-то доступном процессоре и под него все оптимизируется. Опять же Вы упомянули про кэш , а это тоже особенности реализации.
Спасибо. Отличная статья.
Все время забываю про ИИ. Он пишет, что 4К бпф 66-й делает за 26000-29000 тактов при самом лучшем расположении данных. Но меня больше сразила цифра тактов для 16К - 328000. Или 131000 если использовать реализацию на все ядра. Но , конечно, веры в эти цифры нет :)
Когда-то я работал с DSP К1967ВН44. Для ориентира , у него БПФ с такими же числами для 4К- 23420 тактов, 16К - 117930, 64К-635000. Судя по всему у Вас еще не самый лучший результат получился.
Правильно ли я понял, что лучший результат для БПФ 4К комплексных float это 15078 тактов? Сколько тактов такое же БПФ на С66?
Помню, в 97-м прошлого века в КБ при заводе сделали НИР и получили рабочий чип. Затем я увидел ТЗ на ОКР с окончанием в 2013. Я думал, что шутка. Но в 2013 чип реально появился. А Вы говорите 7.5 месяцев. Это если за Вас кто-то все уже сделал :)
Вы , как и я, еще не привыкли к ИИ :) Если задать ему Ваш вопрос по поводу популярности в прошлые годы, то одной из фраз будет такая:" По данным на 2018 год, около 80% проектных групп в мире использовали Verilog или SystemVerilog. "
PS. ИИ рекомендует использовать SCR1 :)
Вот над этим хорошо бы акцентировать внимание. Когда-то я делал ASIC для автомобильного ключа на 8-разрядном МК: ядро+SRAM+ flash+простой последовательный интерфейс. Нажимаем кнопку - подается питание, МК читает из флэша число, шифрует его , отправляет, записывает во флэш новое число и отключается. Какое ядро из этих двух лучше подойдет для такого применения? Требования - чтобы батарейка работала как можно дольше и чип был как можно дешевле.
Не вижу проблем использовать SCR1 в точно такой же конфигурации.
Этот тест был бы информативнее, но на мой взгляд, в статье нужно было немножко больше рассказать об особенностях исполнения команд в PicoRV32. Суть в том, что у него нет никакого конвейера и если вы выставите наилучшие условия для быстрой работы, то даже NOP команда будет исполняться за 3 такта. Если память работает не идеально, т.е. запрос на чтение команды в текущем такте, а сама команда в следующем такте, то уже как минимум 4 такта на любую команду. Поэтому нужно ожидать , что по тактам Picorv32 будет в 4 раза проигрывать SCR1 на одинаковом коде. Если используется С расширение, то иногда команда уже выбрана и тогда для неё 3 такта. Итого ухудшение по тактам будет меньше 4-х. Сравнивать эти ядра как-то даже не интересно если есть мысли о каком-то быстродействии.
Скорее всего причина в том, что в МАХ версии у Вас конвейер 4 стадии, а в МИН только 2. На этом можно сильно потерять из-за переходов.
я посмотрел времянку SCR1 на этом тесте. Скажу так - тест выбран очень неудачно. Сами представьте: всего 453 такта на итерацию в которой только одна операция умножения. Поэтому и выводы такие, что лучше выбирать минимальную конфигурацию SCR1 (без умножения) т.к. она не уступает максимальной (с аппаратным однотактным умножителем). Все верно, но только для этого теста. Попробуйте другой тест.
Спасибо за статью. Подскажите, у Вас в конфигурации IM(max) в обоих ядрах используется однотактный аппаратный умножитель?
Спасибо за уточнение. Поспрашивал ИИ :) Действительно, для экономии и упрощения всего и вся, следующая команда потока не запускается на конвейере пока не завершится предыдущая. ВЫгодно запускать число потоков не меньшее длины конвейера.
нужна табличка всех архитектурных регистров RISC-V и на каждый регистр прописывать общий он для потоков или для каждого индивидуальный.
Напоминает многоядерную систему с общей памятью, в которой арбитр доступа к памяти перенесен в ядро процессора :) Интересно было бы сравнить 8-миядерный однопоточный с одноядерным 8-мипоточным по площади и частоте. Судя по реализации XCORE одному потоку гарантируется 1/8 времени минимум. Хотя при этом нужно еще уметь исполнять первый поток когда второй остановился. Итого чтобы один поток имел 100 МГц , вся система должна работать на 800 МГц. Решение прикольное.
Вопросы показали, что меня бы в YADRO точно не взяли. Я даже про две 1 на входе и 0 на выходе не угадал :(
У меня каждый вечер сверху как будто телега по потолку катается. Это такой же пылесос? А еще как будто стиралка работает . Может это он так заряжается? Надоело конкретно.
Когда-то программировал под ARM и там как раз такое решение - располагать константы в дырках между функциями. Но в данном случае компилятор не пользуется таким приемом, а кладет константу только за кодом.
Да. Код у меня расположен , начиная с 0-го адреса. Секция данных сразу за кодом. Размер кода при -О0 1244 байта, при -О2 1246 байт. Я специально для -О2 вырезал часть кода из ассемблерного стартапа , но компилятор не поменял решения.
LUI+ADDI это типовая склейка в одну команду у RISC-V. Вы правы в предположении.Загрузка константы в простом суперскалере на 2 команды за такт займет максимум 4 такта. Иногда компилятор делает LUI+ADDI не перемешивая. А в конце сдвиг и сложение. Теоретически сдвиг на 32 и сложение тоже можно склеить. Не знаю делают ли так, но в этом случае 3 такта.
Чтобы понять какой вариант быстрее нужен не только тест, но еще нужно выбирать и конкретную реализацию процессора. У меня такое впечатление , что компилятор отлаживают на каком-то доступном процессоре и под него все оптимизируется. Опять же Вы упомянули про кэш , а это тоже особенности реализации.