KGP свежак riscv32 . небеса упали на землю, собрал для масдая... не
идет гора к Магомету. акцент на оптимизацию под популярные
микросхемки, С++26, автовекторизацию кода для векторного расширения
в ch32v407/467 архив
http://klen.org/Files/DevTools/kgcc/x86_64-w64-mingw32_corei7/riscv32-kgp-elf/riscv32-kgp-elf_%40_x86_64-w64-mingw32_corei7.7z
размер 822 999 639 байт
sha256 c87575f9ec8128a30d8cb219366d60f6ca6bbf82b3eca1977820272c8258fd2b
0. добавил описание ядер/конвееров список -mtune=
bumblebee
scr1
qkv2a
qkv2c
qkv3a
qkv3b
qkv3c
qkv3f
qkv3v
qkv4a
qkv4b
qkv4c
qkv4f
qkv4j
qkv5a
qkv5f
1. добавил нативно микросхемки. список -mcpu=
gd32vf103
k1921vg015
k1948vk018
ch32v003
ch641
ch32v002
ch32v004
ch32v005
ch32v006
ch32v007
ch32m007
ch32v103
ch565
ch569
ch571
ch573
ch32m030
ch32v205
ch32v203
ch32v208
ch570
ch572
ch584
ch585
ch587
ch595
ch596
ch32x315
ch32v407
ch32v467
ch582
ch583
ch32x033
ch32x034
ch32x035
ch32l103
ch32m103
ch591 ch592
ch643
ch645
ch32v303
ch32v305
ch32v307
ch32v317
ch564
ch32v415_qkv3f
ch32v415_qkv5f
ch32v416_qkv3f
ch32v416_qkv5f
ch32v417_qkv3f
ch32v417_qkv5f
ЗАМЕЧАНИЕ #0: про -mtune -mcpu следует понимать так - есть три "философские категории" - а) архитектура ( задает набор инструкций -march= ) б) процессорное ядро/конвейер ( задает физические свойства реализации архитектуры -mtune=. например цены инструкций, взаимное влияние друг на друга, задержки, цены не выровненного доступа, учет количество потоков АЛУ, возможности спаривания команд, ступенчатость конвейера и тд ) в) собсно процессор/микросхема - объеденяет и сопоставляет комбинацию первого и второго.
например -march=rv32imacf -mtune=qkv4f это эквивалент -mcpu=ch32v307
это эквивалент -mcpu=ch32v305.
-march=rv32imacf -mtune=qkv5f скорее всего даст другой код - конвеер qkv5f отличается от qkv4f, поэтому оптимизатор может учесть спаривание команд и учесть супенчатость qkv5f
если воткнуть только -march=rv32imacf, то будет сгенерен код с инструкциями набора imacf и будет работать на обоих микросхемах но оно не учет особенности описанные в qkv4f и qkv5f
таким образом для обывателя-ползователя kgp - нужнго втыкнуть ключ -mcpu с именем микросхемки или ручками указать реализованные в текущей реализации компилятора -march= -mtune=
если ядро/конвейер не описан то достаточно -march= и указать набор инструкций.
посмотреть что имеется доступное смотреть так
riscv32-kgp-elf-gcc --target-help
2. Мультилиб. этот термин в рамках компилятора означает соответствие между набором ключей компиляции и конкретного набора библиотек(собранных с этими же ключами) которые будут залинкованы в бинарь при сборке.
этот механизм служить только одной цели - подсунуть на этапе линковки (по результатам анализа ключей) самые подходящие оптимизированные версии библиотек. ничего более умного тут нет.
таким образом библиотеки в рамках компилятора libgcc.a libc.a libc_nano.a libm.a libm_nano.a libstdc++.a libsup++.a и тд собираются для всех описанных комбинаций ключей чтоб выбрать "правильно оптимизированный мультитиб"
мультилибы хранятся в
./riscv32-kgp-elf_@_x86_64-w64-mingw32_corei7/lib/gcc/riscv32-kgp-elf/16.0.1/kgp/*
./riscv32-kgp-elf_@_x86_64-w64-mingw32_corei7/riscv32-kgp-elf/lib/kgp/*
проверить че там в мультилиб накомпилял майнтейнер(в данном случае это я) компилятора можно смотреть так
riscv32-kgp-elf-gcc --print-multi-lib
в нашем случае компиллер сообщит следующее:
kgp/rv32ec.ilp32e.medlow;@march=rv32ec@mabi=ilp32e@mcmodel=medlow
kgp/rv32ec.ilp32e.medlow.Oz;@march=rv32ec@mabi=ilp32e@mcmodel=medlow@Oz
kgp/rv32ec.ilp32e.medlow.Ofast;@march=rv32ec@mabi=ilp32e@mcmodel=medlow@Ofast
kgp/rv32ec.ilp32e.medlow.Os;@march=rv32ec@mabi=ilp32e@mcmodel=medlow@Os
kgp/rv32ec.ilp32e.medlow.O2;@march=rv32ec@mabi=ilp32e@mcmodel=medlow@O2
kgp/rv32ec.ilp32e.medlow.O3;@march=rv32ec@mabi=ilp32e@mcmodel=medlow@O3
kgp/rv32emc.ilp32e.medlow;@march=rv32emc@mabi=ilp32e@mcmodel=medlow
kgp/rv32emc.ilp32e.medlow.Oz;@march=rv32emc@mabi=ilp32e@mcmodel=medlow@Oz
kgp/rv32emc.ilp32e.medlow.Ofast;@march=rv32emc@mabi=ilp32e@mcmodel=medlow@Ofast
kgp/rv32emc.ilp32e.medlow.Os;@march=rv32emc@mabi=ilp32e@mcmodel=medlow@Os
kgp/rv32emc.ilp32e.medlow.O2;@march=rv32emc@mabi=ilp32e@mcmodel=medlow@O2
kgp/rv32emc.ilp32e.medlow.O3;@march=rv32emc@mabi=ilp32e@mcmodel=medlow@O3
kgp/rv32imc.ilp32.medlow;@march=rv32imc@mabi=ilp32@mcmodel=medlow
kgp/rv32imc.ilp32.medlow.Oz;@march=rv32imc@mabi=ilp32@mcmodel=medlow@Oz
kgp/rv32imc.ilp32.medlow.Ofast;@march=rv32imc@mabi=ilp32@mcmodel=medlow@Ofast
kgp/rv32imc.ilp32.medlow.Os;@march=rv32imc@mabi=ilp32@mcmodel=medlow@Os
kgp/rv32imc.ilp32.medlow.O2;@march=rv32imc@mabi=ilp32@mcmodel=medlow@O2
kgp/rv32imc.ilp32.medlow.O3;@march=rv32imc@mabi=ilp32@mcmodel=medlow@O3
kgp/rv32imcb.ilp32.medlow;@march=rv32imcb@mabi=ilp32@mcmodel=medlow
kgp/rv32imcb.ilp32.medlow.Oz;@march=rv32imcb@mabi=ilp32@mcmodel=medlow@Oz
kgp/rv32imcb.ilp32.medlow.Ofast;@march=rv32imcb@mabi=ilp32@mcmodel=medlow@Ofast
kgp/rv32imcb.ilp32.medlow.Os;@march=rv32imcb@mabi=ilp32@mcmodel=medlow@Os
kgp/rv32imcb.ilp32.medlow.O2;@march=rv32imcb@mabi=ilp32@mcmodel=medlow@O2
kgp/rv32imcb.ilp32.medlow.O3;@march=rv32imcb@mabi=ilp32@mcmodel=medlow@O3
kgp/rv32imac.ilp32.medlow;@march=rv32imac@mabi=ilp32@mcmodel=medlow
kgp/rv32imac.ilp32.medlow.Oz;@march=rv32imac@mabi=ilp32@mcmodel=medlow@Oz
kgp/rv32imac.ilp32.medlow.Ofast;@march=rv32imac@mabi=ilp32@mcmodel=medlow@Ofast
kgp/rv32imac.ilp32.medlow.Os;@march=rv32imac@mabi=ilp32@mcmodel=medlow@Os
kgp/rv32imac.ilp32.medlow.O2;@march=rv32imac@mabi=ilp32@mcmodel=medlow@O2
kgp/rv32imac.ilp32.medlow.O3;@march=rv32imac@mabi=ilp32@mcmodel=medlow@O3
kgp/rv32imac_zba_zbb_zbc_zbs_zve64x_zvl64b_zve32x_zvkb_zvl32b_zvbb_zaamo_zalrsc.ilp32.medlow;@march=rv32imac_zba_zbb_zbc_zbs_zve64x_zvl64b_zve32x_zvkb_zvl32b_zvbb_zaamo_zalrsc@mabi=ilp32@mcmodel=medlow
kgp/rv32imac_zba_zbb_zbc_zbs_zve64x_zvl64b_zve32x_zvkb_zvl32b_zvbb_zaamo_zalrsc.ilp32.medlow.Oz;@march=rv32imac_zba_zbb_zbc_zbs_zve64x_zvl64b_zve32x_zvkb_zvl32b_zvbb_zaamo_zalrsc@mabi=ilp32@mcmodel=medlow@Oz
kgp/rv32imac_zba_zbb_zbc_zbs_zve64x_zvl64b_zve32x_zvkb_zvl32b_zvbb_zaamo_zalrsc.ilp32.medlow.Ofast;@march=rv32imac_zba_zbb_zbc_zbs_zve64x_zvl64b_zve32x_zvkb_zvl32b_zvbb_zaamo_zalrsc@mabi=ilp32@mcmodel=medlow@Ofast
kgp/rv32imac_zba_zbb_zbc_zbs_zve64x_zvl64b_zve32x_zvkb_zvl32b_zvbb_zaamo_zalrsc.ilp32.medlow.Os;@march=rv32imac_zba_zbb_zbc_zbs_zve64x_zvl64b_zve32x_zvkb_zvl32b_zvbb_zaamo_zalrsc@mabi=ilp32@mcmodel=medlow@Os
kgp/rv32imac_zba_zbb_zbc_zbs_zve64x_zvl64b_zve32x_zvkb_zvl32b_zvbb_zaamo_zalrsc.ilp32.medlow.O2;@march=rv32imac_zba_zbb_zbc_zbs_zve64x_zvl64b_zve32x_zvkb_zvl32b_zvbb_zaamo_zalrsc@mabi=ilp32@mcmodel=medlow@O2
kgp/rv32imac_zba_zbb_zbc_zbs_zve64x_zvl64b_zve32x_zvkb_zvl32b_zvbb_zaamo_zalrsc.ilp32.medlow.O3;@march=rv32imac_zba_zbb_zbc_zbs_zve64x_zvl64b_zve32x_zvkb_zvl32b_zvbb_zaamo_zalrsc@mabi=ilp32@mcmodel=medlow@O3
kgp/rv32imcf_zba_zbb_zbc_zbs.ilp32f.medlow;@march=rv32imcf_zba_zbb_zbc_zbs@mabi=ilp32f@mcmodel=medlow
kgp/rv32imcf_zba_zbb_zbc_zbs.ilp32f.medlow.0z;@march=rv32imcf_zba_zbb_zbc_zbs@mabi=ilp32f@mcmodel=medlow@Oz
kgp/rv32imcf_zba_zbb_zbc_zbs.ilp32f.medlow.Ofast;@march=rv32imcf_zba_zbb_zbc_zbs@mabi=ilp32f@mcmodel=medlow@Ofast
kgp/rv32imcf_zba_zbb_zbc_zbs.ilp32f.medlow.Os;@march=rv32imcf_zba_zbb_zbc_zbs@mabi=ilp32f@mcmodel=medlow@Os
kgp/rv32imcf_zba_zbb_zbc_zbs.ilp32f.medlow.O2;@march=rv32imcf_zba_zbb_zbc_zbs@mabi=ilp32f@mcmodel=medlow@O2
kgp/rv32imcf_zba_zbb_zbc_zbs.ilp32f.medlow.O3;@march=rv32imcf_zba_zbb_zbc_zbs@mabi=ilp32f@mcmodel=medlow@O3
kgp/rv32imafc.ilp32f.medlow;@march=rv32imafc@mabi=ilp32f@mcmodel=medlow
kgp/rv32imafc.ilp32f.medlow.Oz;@march=rv32imafc@mabi=ilp32f@mcmodel=medlow@Oz
kgp/rv32imafc.ilp32f.medlow.Ofast;@march=rv32imafc@mabi=ilp32f@mcmodel=medlow@Ofast
kgp/rv32imafc.ilp32f.medlow.Os;@march=rv32imafc@mabi=ilp32f@mcmodel=medlow@Os
kgp/rv32imafc.ilp32f.medlow.O2;@march=rv32imafc@mabi=ilp32f@mcmodel=medlow@O2
kgp/rv32imafc.ilp32f.medlow.O3;@march=rv32imafc@mabi=ilp32f@mcmodel=medlow@O3
kgp/rv32imafcb.ilp32f.medlow;@march=rv32imafcb@mabi=ilp32f@mcmodel=medlow
kgp/rv32imafcb.ilp32f.medlow.Oz;@march=rv32imafcb@mabi=ilp32f@mcmodel=medlow@Oz
kgp/rv32imafcb.ilp32f.medlow.Ofast;@march=rv32imafcb@mabi=ilp32f@mcmodel=medlow@Ofast
kgp/rv32imafcb.ilp32f.medlow.Os;@march=rv32imafcb@mabi=ilp32f@mcmodel=medlow@Os
kgp/rv32imafcb.ilp32f.medlow.O2;@march=rv32imafcb@mabi=ilp32f@mcmodel=medlow@O2
kgp/rv32imafcb.ilp32f.medlow.O3;@march=rv32imafcb@mabi=ilp32f@mcmodel=medlow@O3
это список папок в которых хранятся версии библиотек .
при втыкании ключей линкер их анализирует и пытается найти соответствие и выбрать папку с набором библиотек.
смотреть какой мультилиб линкер пытается выбрать для линковки смотреть так
пример в нашем случае:

ВАЖНО!!! из описанного должно быть ясно - при линковке нужно пихать все те же ключи что и при компиляции приложения и библиотек. чтоб все совпало.
казалось бы зачем линкеру -Os ? линкер жеж ничего не компиляет..... нужно! по этому ключу он в том числе будет искать путь мультилиба :)
для справки апа микросхем к их архитектурам и ядрам:
kgp/rv32ec ilp32e.medlow RISCV_CORE("ch32v003", "rv32ec_zicsr_zifencei", "qkv2a")
RISCV_CORE("ch641", "rv32ec_zicsr_zifencei", "qkv2a")
kgp/rv32emc ilp32e.medlow RISCV_CORE("ch32v002", "rv32emc_zicsr_zifencei", "qkv2c")
RISCV_CORE("ch32v004", "rv32emc_zicsr_zifencei", "qkv2c")
RISCV_CORE("ch32v005", "rv32emc_zicsr_zifencei", "qkv2c")
RISCV_CORE("ch32v006", "rv32emc_zicsr_zifencei", "qkv2c")
RISCV_CORE("ch32v007", "rv32emc_zicsr_zifencei", "qkv2c")
RISCV_CORE("ch32m007", "rv32emc_zicsr_zifencei", "qkv2c")
kgp/rv32imc ilp32.medlow RISCV_CORE("k1948vk018", "rv32imc_zicsr_zifencei", "scr1")
kgp/rv32imcb ilp32.medlow RISCV_CORE("ch32m030", "rv32imcb_zicsr_zifencei", "qkv3b")
RISCV_CORE("ch32v205", "rv32imcb_zicsr_zifencei", "qkv3b")
RISCV_CORE("ch570", "rv32imcb_zicsr_zifencei", "qkv3c")
RISCV_CORE("ch572", "rv32imcb_zicsr_zifencei", "qkv3c")
RISCV_CORE("ch584", "rv32imcb_zicsr_zifencei", "qkv3c")
RISCV_CORE("ch585", "rv32imcb_zicsr_zifencei", "qkv3c")
RISCV_CORE("ch587", "rv32imcb_zicsr_zifencei", "qkv3c")
RISCV_CORE("ch595", "rv32imcb_zicsr_zifencei", "qkv3c")
RISCV_CORE("ch596", "rv32imcb_zicsr_zifencei", "qkv3c")
kgp/rv32imac ilp32.medlow RISCV_CORE("gd32vf103", "rv32imac_zicsr_zifencei", "bumblebee")
RISCV_CORE("ch32v103", "rv32imac_zicsr_zifencei", "qkv3a")
RISCV_CORE("ch565", "rv32imac_zicsr_zifencei", "qkv3a")
RISCV_CORE("ch569", "rv32imac_zicsr_zifencei", "qkv3a")
RISCV_CORE("ch571", "rv32imac_zicsr_zifencei", "qkv3a")
RISCV_CORE("ch573", "rv32imac_zicsr_zifencei", "qkv3a")
RISCV_CORE("ch582", "rv32imac_zicsr_zifencei", "qkv4a")
RISCV_CORE("ch583", "rv32imac_zicsr_zifencei", "qkv4a")
RISCV_CORE("ch32v203", "rv32imac_zicsr_zifencei", "qkv4b")
RISCV_CORE("ch32v208", "rv32imac_zicsr_zifencei", "qkv4c")
RISCV_CORE("ch32x033", "rv32imac_zicsr_zifencei", "qkv4c")
RISCV_CORE("ch32x034", "rv32imac_zicsr_zifencei", "qkv4c")
RISCV_CORE("ch32x035", "rv32imac_zicsr_zifencei", "qkv4c")
RISCV_CORE("ch32l103", "rv32imac_zicsr_zifencei", "qkv4c")
RISCV_CORE("ch32m103", "rv32imac_zicsr_zifencei", "qkv4c")
RISCV_CORE("ch591", "rv32imac_zicsr_zifencei", "qkv4c")
RISCV_CORE("ch592", "rv32imac_zicsr_zifencei", "qkv4c")
RISCV_CORE("ch643", "rv32imac_zicsr_zifencei", "qkv4c")
RISCV_CORE("ch645", "rv32imac_zicsr_zifencei", "qkv4c")
RISCV_CORE("ch564", "rv32imac_zicsr_zifencei", "qkv4j")
kgp/rv32imac_zba_zbb_zbc_zbs_zve64x_zvl64b_zve32x_zvkb_zvl32b_zvbb_zaamo_zalrsc ilp32.medlow RISCV_CORE("ch32v407", "rv32imac_zba_zbb_zbc_zbs_zve64x_zvl64b_zve32x_zvkb_zvl32b_zvbb_zaamo_zalrsc", "qkv3v")
RISCV_CORE("ch32v467", "rv32imac_zicsr_zifencei_zba_zbb_zbc_zbs_zve64x_zvl64b_zvbb", "qkv3v")
kgp/rv32imcf_zba_zbb_zbc_zbs ilp32f.medlow RISCV_CORE("к1921вг015", "rv32imcf_zicsr_zifencei_zba_zbb_zbc_zbs", "cloudbear-bm310s6")
RISCV_CORE("k1921vg015", "rv32imcf_zicsr_zifencei_zba_zbb_zbc_zbs", "cloudbear-bm310s6")
kgp/rv32imafc ilp32f.medlow RISCV_CORE("ch32v303", "rv32imafc_zicsr_zifencei", "qkv4f")
RISCV_CORE("ch32v305", "rv32imafc_zicsr_zifencei", "qkv4f")
RISCV_CORE("ch32v307", "rv32imafc_zicsr_zifencei", "qkv4f")
RISCV_CORE("ch32v317", "rv32imafc_zicsr_zifencei", "qkv4f")
kgp/rv32imafcb ilp32f.medlow RISCV_CORE("ch32x315", "rv32imafcb_zicsr_zifencei", "qkv3f")
RISCV_CORE("ch32v415_qkv3f", "rv32imafcb_zicsr_zifencei", "qkv3f")
RISCV_CORE("ch32v415_qkv5f", "rv32imafcb_zicsr_zifencei", "qkv5f")
RISCV_CORE("ch32v416_qkv3f", "rv32imafcb_zicsr_zifencei", "qkv3f")
RISCV_CORE("ch32v416_qkv5f", "rv32imafcb_zicsr_zifencei", "qkv5f")
RISCV_CORE("ch32v417_qkv3f", "rv32imafcb_zicsr_zifencei", "qkv3f")
RISCV_CORE("ch32v417_qkv5f", "rv32imafcb_zicsr_zifencei", "qkv5f")
3. Для натягивания компилятора на MRS2 нужно
а) положить архив куда то и прописать PATH в riscv32-kgp-elf_@_x86_64-w64-mingw32_corei7/bin/
проверить что все работает так

б) добавить сторонний toolchain в MRS2
в) в выбранном проекте MRS2 выключить все дурацкие -march -mtune -mcpu настройки которые среда делает за нас (нет ничего хуже) и в other target flags указать то что нужно


ЗАМЕЧАНИЕ #1. если вы внимательно посмотрели на имена папок мультилиба, то могли заметить что там есть еще комбинации -mcmodel = -mabi- и ключи оптимизации -Oxxx
таки образом чтобы попасть линкером в нужны мультилиб нужно одновременно указать
-march -mcmodel -mabi -O
либо
-mcpu -mcmodel -mabi -O
в приципе в мультилиб можно для заданной архитектуры можно добавить -mtune и подробить еще на оптимизации для разных ядер..... но тогда список папок с вариантами библиотек растут как факториал..... сборка удлинняется до часов, размер дистра до гигабайт.
поэтому для себя я обычно выбираю микросхему с корой рабоаю в данный момент и собираю для нее по все дырам как можно больше чего можно выжать из текущего комилятора.
на этой сборке впервые у нас появился микросхема ch32v407/467 с процессором оснащенным векторными расширениями RVV e64.
данный компилятор версии 16.0.1 умеет переваривать даже если вы ничего не знаете про RVV - примерно так как SSE или AVX в x86_64
про это в следущем посте в этом разделе.
зы. букв много, читать длинно - звиняте. как то так. для Вас старалсо!