Comments 20
Похвально, что Вы не бросили свою затею. Обычно обещающие здесь многотомную эпопею, первой публикацией и ограничиваются.
однотактное умножение не так уж и нужно
Да, если Вы посчитаете , сколько в коремарке выполнилось команд умножения и сколько на них потратилось тактов (для многотактной версии), то получится где-то менее 7 тактов на умножение. В тесте очень удобные числа для Вашей реализации.
И не только в тесте. Для чего обычно используется умножение в общем коде? Если надо превратить arr[i] в arr + i * sizeof(arr[0]). Очевидно, в таком умножении много тактов и не понадобится, потому что i редко за 1000 переваливает, а sizeof тем более.
Что скажете насчёт быстрого деления? Быстрее флагманов получится?
Для чего обычно используется умножение в общем коде?
А если взять какую нибудь криптографию...
Деление у Вас просто огонь. В тактах, конечно. Вот только не знаю какой бы тест подобрать чтобы надрать задницу флагманам :)
Ещё важный пункт, деления почти не вызываются во время теста, так что влияние нового алгоритма лучше проверять на чём-то другом.
Шикарная работа, но в CoreMark вроде нет деления?
Однотактное умножение в ПЛИС влазит (но оно там есть и так ) и занимает 2000LUT и тактовая 50MHz.
Но шибко лютый CoreMark получился, 2.7CM/MHz выглядит уж круто , как у Cortex M0. у PicoRV32 0.57, но умножитель на на ПЛИСе всегда однотактовый.
Хорошая статья, есть надо чем подумать... (Вообще бесконечно можно делать три вещи- смотреть как течет вода, смотреть как горит огонь, и запускать CoreMark))
На скриншоте x = 7D0, y = 3, это вычисление размера теста, 2000/3=666. Ещё форматирование %d вызывает 2 деления на цифру. Если ворочать json, наверное там бы кэширование деления пригодилось, чтобы частное и остаток два раза не вычислять.
С появлением конвейера CM просядет совсем немножко, об этом в следующей статье, если соберусь.
Дак это на результат не влияет, stop_time() вызывается до вывода. Там в настройка есть сколько тиков в секунде. Но в любом случае спасибо, класная работа, пойду свое ядро мучать, смотреть где мои 2.7 Cm/Mhz
PS. Хотя нет, я извиняюсь за занудство.
Результат теста во втрой статье $finish дает количество тиков 1,629,813 это развне не должно биться с Total ticks? Применяя аппаратное умножение $finish 802303 в два раза быстрее. В тестбенче `timescale 1ns / 1ns
. Если бы тактовая была 1Mhz то в первом случае итерация бы заняла 1,6 секунды, вовтором 0.8. В первом случае у Вас 0,625 Cm/Mhz во втором 1, 25 как у всех однотактников. Где я ошибся?
1 наносекунда на низ меандра, одна наносекунда на верх, так что число тиков надо делить на два.
со всеми однотактными командами у меня одна итерация 313 263 такта. Это 3.1922
В чём запускаете? У меня одна итерация однотактного варианта в икарусе занимает 9 минут, поэтому по умолчанию отключена.
Стойте стойте, а почему вы собираете %gcc_bin%-gcc %ccflags% -c src/core_list_join.c -o build/core_list_join.o
А где matrix?
Но шибко лютый CoreMark получился, 2.7CM/MHz выглядит уж круто
Модель интересна тем, что она однотактовая. В ней напрочь отсутствует конвейер. Любая команда исполняется за 1 такт. Вы не теряете ничего на переходах, на загрузке данных. т.е. это какой-то идеал , к которому нужно стремиться. :)
Подначиваете следующую статью писать. Удивляться надо будет, если ядра через Ctrl+C, Ctrl+V накопируются и начнут поток параллельно крутить, вот там можно i7 по числу команд за такт обогнать.
В пределе с одним набором регистров (32 штуки) можно за такт 10 команд выполнять. А если вторую копию завести и учесть float, то ещё больше.
Процессор на коленке ч.3. Алгоритм быстрого деления