кто не в курсе - у ST не так давно появилась свежая серия микроконтроллеров серии stm32n6
https://www.st.com/en/microcontrollers-microprocessors/stm32n6-series.html
она содержит cortex-m55 который в свою очередь имеет связку даблового fpu и векторного расширения MVE ( другое название Helium )
доки на него
arm-hel…ing_for_helium_102095_0101_02_en.pdf
если коротко то отличия Гелия от Неона
из интересного видно что кроме прочего векторизация расширена в Гелии на целочисленные операции на целочисленных регистрах.
судя по всему если захочется векторная арифметика с фиксированной запятой - можно использовать как целые регистры так и плавающие
должно быть быстрее чем Неон
понятно что на асме или интринсиках мы вытянем все возможности из Гелия, но как всегда хоцца шоб компиллер сделла за нас ленивых работу - в GCC и LLVM есть такая фигня - auto-vectorization. при ее втыкании он пытается распреллелить дерево операций и если это получилось использовать для этого инструкции из векторного набора
https://gcc.gnu.org/projects/tree-ssa/vectorization.html
вот че получилось
исходник
#include <stdint.h> #include <stddef.h>
void FooInt32(const int* __restrict__ a, const int* __restrict__ b, const int* __restrict__ c, const int* __restrict__ d, int* e, const size_t s) { for ( size_t i = 0 ; i < s ; i++ ) { e[i] = a[i ]*b[i ] - c[i ]*d[i ] ; } } void FooFloat32(const float* __restrict__ a, const float* __restrict__ b, const float* __restrict__ c, const float* __restrict__ d, float* e, const size_t s) { for ( size_t i = 0 ; i < s ; i++ ) { e[i] = a[i ]*b[i ] - c[i ]*d[i ] ; } }
функции нак написаны чтоб была явная парралеизация трассы вычисления
arm-kgp-eabi-gcc -g0 -c a.cc -Ofast -g0 -mcpu=cortex-m55 -mthumb -mfloat-abi=hard
00000000 <_Z8FooInt32PKiS0_S0_S0_Pij>: 0: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} 4: e9dd 4608 ldrd r4, r6, [sp, #32] 8: 2e00 cmp r6, #0 a: d06a beq.n e2 <_Z8FooInt32PKiS0_S0_S0_Pij+0xe2> c: 4699 mov r9, r3 e: 1e73 subs r3, r6, #1 10: 2b02 cmp r3, #2 12: 4607 mov r7, r0 14: 4688 mov r8, r1 16: 4615 mov r5, r2 18: d965 bls.n e6 <_Z8FooInt32PKiS0_S0_S0_Pij+0xe6> 1a: ea4f 0a96 mov.w sl, r6, lsr #2 1e: ea4f 1e0a mov.w lr, sl, lsl #4 22: f1ae 0e10 sub.w lr, lr, #16 26: ea4f 1e1e mov.w lr, lr, lsr #4 2a: f10e 0e01 add.w lr, lr, #1 2e: f04e e001 dls lr, lr 32: f04f 0c00 mov.w ip, #0 36: eb09 030c add.w r3, r9, ip 3a: eb07 000c add.w r0, r7, ip 3e: eb08 010c add.w r1, r8, ip 42: eb05 020c add.w r2, r5, ip 46: ed93 3f00 vldrw.u32 q1, [r3, #0] 4a: ed90 7f00 vldrw.u32 q3, [r0, #0] 4e: ed91 1f00 vldrw.u32 q0, [r1, #0] 52: ed92 5f00 vldrw.u32 q2, [r2, #0] 56: ef26 6950 vmul.i32 q3, q3, q0 5a: ef24 4952 vmul.i32 q2, q2, q1 5e: ff26 6844 vsub.i32 q3, q3, q2 62: eb04 030c add.w r3, r4, ip 66: ed83 7f00 vstrw.32 q3, [r3, #0] 6a: f10c 0c10 add.w ip, ip, #16 6e: f00f c01f le lr, 36 <_Z8FooInt32PKiS0_S0_S0_Pij+0x36> 72: ebb6 0f8a cmp.w r6, sl, lsl #2 76: ea4f 008a mov.w r0, sl, lsl #2 7a: d032 beq.n e2 <_Z8FooInt32PKiS0_S0_S0_Pij+0xe2> 7c: f858 2020 ldr.w r2, [r8, r0, lsl #2] 80: f857 3020 ldr.w r3, [r7, r0, lsl #2] 84: f859 1020 ldr.w r1, [r9, r0, lsl #2] 88: fb02 f303 mul.w r3, r2, r3 8c: f855 2020 ldr.w r2, [r5, r0, lsl #2] 90: fb01 3312 mls r3, r1, r2, r3 94: 1c42 adds r2, r0, #1 96: 4296 cmp r6, r2 98: f844 3020 str.w r3, [r4, r0, lsl #2] 9c: ea4f 0380 mov.w r3, r0, lsl #2 a0: d91f bls.n e2 <_Z8FooInt32PKiS0_S0_S0_Pij+0xe2> a2: f103 0c04 add.w ip, r3, #4 a6: f858 100c ldr.w r1, [r8, ip] aa: f857 200c ldr.w r2, [r7, ip] ae: f100 0e02 add.w lr, r0, #2 b2: fb01 f202 mul.w r2, r1, r2 b6: f859 000c ldr.w r0, [r9, ip] ba: f855 100c ldr.w r1, [r5, ip] be: 4576 cmp r6, lr c0: fb00 2211 mls r2, r0, r1, r2 c4: f844 200c str.w r2, [r4, ip] c8: d90b bls.n e2 <_Z8FooInt32PKiS0_S0_S0_Pij+0xe2> ca: 3308 adds r3, #8 cc: 58f8 ldr r0, [r7, r3] ce: f858 2003 ldr.w r2, [r8, r3] d2: f859 1003 ldr.w r1, [r9, r3] d6: fb00 f202 mul.w r2, r0, r2 da: 58e8 ldr r0, [r5, r3] dc: fb00 2211 mls r2, r0, r1, r2 e0: 50e2 str r2, [r4, r3] e2: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} e6: 2000 movs r0, #0 e8: e7c8 b.n 7c <_Z8FooInt32PKiS0_S0_S0_Pij+0x7c> ea: bf00 nop 000000ec <_Z10FooFloat32PKfS0_S0_S0_Pfj>: ec: e92d 47f0 stmdb sp!, {r4, r5, r6, r7, r8, r9, sl, lr} f0: e9dd 4608 ldrd r4, r6, [sp, #32] f4: 2e00 cmp r6, #0 f6: f000 8083 beq.w 200 <_Z10FooFloat32PKfS0_S0_S0_Pfj+0x114> fa: 4699 mov r9, r3 fc: 1e73 subs r3, r6, #1 fe: 2b02 cmp r3, #2 100: 4605 mov r5, r0 102: 460f mov r7, r1 104: 4690 mov r8, r2 106: d97d bls.n 204 <_Z10FooFloat32PKfS0_S0_S0_Pfj+0x118> 108: ea4f 0a96 mov.w sl, r6, lsr #2 10c: ea4f 1e0a mov.w lr, sl, lsl #4 110: f1ae 0e10 sub.w lr, lr, #16 114: ea4f 1e1e mov.w lr, lr, lsr #4 118: f10e 0e01 add.w lr, lr, #1 11c: f04e e001 dls lr, lr 120: f04f 0c00 mov.w ip, #0 124: eb09 030c add.w r3, r9, ip 128: eb05 000c add.w r0, r5, ip 12c: eb07 010c add.w r1, r7, ip 130: eb08 020c add.w r2, r8, ip 134: ed93 3f00 vldrw.u32 q1, [r3, #0] 138: ed90 7f00 vldrw.u32 q3, [r0, #0] 13c: ed91 1f00 vldrw.u32 q0, [r1, #0] 140: ed92 5f00 vldrw.u32 q2, [r2, #0] 144: ff06 6d50 vmul.f32 q3, q3, q0 148: ff04 4d52 vmul.f32 q2, q2, q1 14c: ef26 6d44 vsub.f32 q3, q3, q2 150: eb04 030c add.w r3, r4, ip 154: ed83 7f00 vstrw.32 q3, [r3, #0] 158: f10c 0c10 add.w ip, ip, #16 15c: f00f c01f le lr, 124 <_Z10FooFloat32PKfS0_S0_S0_Pfj+0x38> 160: ebb6 0f8a cmp.w r6, sl, lsl #2 164: ea4f 038a mov.w r3, sl, lsl #2 168: d04a beq.n 200 <_Z10FooFloat32PKfS0_S0_S0_Pfj+0x114> 16a: eb08 0283 add.w r2, r8, r3, lsl #2 16e: ed92 6a00 vldr s12, [r2] 172: eb09 0283 add.w r2, r9, r3, lsl #2 176: edd2 7a00 vldr s15, [r2] 17a: eb05 0283 add.w r2, r5, r3, lsl #2 17e: edd2 6a00 vldr s13, [r2] 182: eb07 0283 add.w r2, r7, r3, lsl #2 186: ed92 7a00 vldr s14, [r2] 18a: ee67 7ac6 vnmul.f32 s15, s15, s12 18e: eee6 7a87 vfma.f32 s15, s13, s14 192: 1c5a adds r2, r3, #1 194: eb04 0083 add.w r0, r4, r3, lsl #2 198: 4296 cmp r6, r2 19a: edc0 7a00 vstr s15, [r0] 19e: ea4f 0183 mov.w r1, r3, lsl #2 1a2: d92d bls.n 200 <_Z10FooFloat32PKfS0_S0_S0_Pfj+0x114> 1a4: 1d0a adds r2, r1, #4 1a6: eb08 0002 add.w r0, r8, r2 1aa: ed90 6a00 vldr s12, [r0] 1ae: eb09 0002 add.w r0, r9, r2 1b2: edd0 7a00 vldr s15, [r0] 1b6: 18a8 adds r0, r5, r2 1b8: edd0 6a00 vldr s13, [r0] 1bc: 18b8 adds r0, r7, r2 1be: ed90 7a00 vldr s14, [r0] 1c2: ee67 7ac6 vnmul.f32 s15, s15, s12 1c6: eee6 7a87 vfma.f32 s15, s13, s14 1ca: 3302 adds r3, #2 1cc: 4422 add r2, r4 1ce: 429e cmp r6, r3 1d0: edc2 7a00 vstr s15, [r2] 1d4: d914 bls.n 200 <_Z10FooFloat32PKfS0_S0_S0_Pfj+0x114> 1d6: f101 0308 add.w r3, r1, #8 1da: 4499 add r9, r3 1dc: 4498 add r8, r3 1de: ed99 6a00 vldr s12, [r9] 1e2: edd8 7a00 vldr s15, [r8] 1e6: 441f add r7, r3 1e8: 441d add r5, r3 1ea: edd7 6a00 vldr s13, [r7] 1ee: ed95 7a00 vldr s14, [r5] 1f2: ee67 7ac6 vnmul.f32 s15, s15, s12 1f6: eee6 7a87 vfma.f32 s15, s13, s14 1fa: 441c add r4, r3 1fc: edc4 7a00 vstr s15, [r4] 200: e8bd 87f0 ldmia.w sp!, {r4, r5, r6, r7, r8, r9, sl, pc} 204: 2300 movs r3, #0 206: e7b0 b.n 16a <_Z10FooFloat32PKfS0_S0_S0_Pfj+0x7e>
выше жирнентким выделеныинструкции Гелия и выдно что он трактует регистровый файл FPU как набор 128 битных регистров
если отключить авто-векторизацию то компиллер сгенерить код под FP сопроцессор
arm-kgp-eabi-gcc -g0 -c a.cc -Os -g0 -mcpu=cortex-m55 -mthumb -mfloat-abi=hard
00000000 <_Z8FooInt32PKiS0_S0_S0_Pij>: 0: b5f0 push {r4, r5, r6, r7, lr} 2: 9d06 ldr r5, [sp, #24] 4: 2400 movs r4, #0 6: f105 0e01 add.w lr, r5, #1 a: f04e e001 dls lr, lr e: f1be 0e01 subs.w lr, lr, #1 12: d100 bne.n 16 <_Z8FooInt32PKiS0_S0_S0_Pij+0x16> 14: bdf0 pop {r4, r5, r6, r7, pc} 16: f851 7024 ldr.w r7, [r1, r4, lsl #2] 1a: f850 5024 ldr.w r5, [r0, r4, lsl #2] 1e: f853 6024 ldr.w r6, [r3, r4, lsl #2] 22: 437d muls r5, r7 24: f852 7024 ldr.w r7, [r2, r4, lsl #2] 28: fb06 5517 mls r5, r6, r7, r5 2c: 9e05 ldr r6, [sp, #20] 2e: f846 5024 str.w r5, [r6, r4, lsl #2] 32: 3401 adds r4, #1 34: e7eb b.n e <_Z8FooInt32PKiS0_S0_S0_Pij+0xe> 00000036 <_Z10FooFloat32PKfS0_S0_S0_Pfj>: 36: b530 push {r4, r5, lr} 38: e9dd 5403 ldrd r5, r4, [sp, #12] 3c: f024 4440 bic.w r4, r4, #3221225472 @ 0xc0000000 40: f104 0e01 add.w lr, r4, #1 44: f04e e001 dls lr, lr 48: f1be 0e01 subs.w lr, lr, #1 4c: d100 bne.n 50 <_Z10FooFloat32PKfS0_S0_S0_Pfj+0x1a> 4e: bd30 pop {r4, r5, pc} 50: ecb2 6a01 vldmia r2!, {s12} 54: ecf3 7a01 vldmia r3!, {s15} 58: ecf0 6a01 vldmia r0!, {s13} 5c: ecb1 7a01 vldmia r1!, {s14} 60: ee67 7ac6 vnmul.f32 s15, s15, s12 64: eee6 7a87 vfma.f32 s15, s13, s14 68: ece5 7a01 vstmia r5!, {s15} 6c: e7ec b.n 48 <_Z10FooFloat32PKfS0_S0_S0_Pfj+0x12>
ну что ж... будем посмотреть как быстро ускорится FFT (в Гелии реализованы инструкции с комплексными числами), матричная арифметика и прочие собачьи радости.
-
- Где покупали NUCLEO-N657X0-Q и почём. Дайте плз ссылку. - STM32любитeль(02.07.2025 00:23,
)
- Ali klen(1 знак., 02.07.2025 01:21, ссылка)
- Спасибо за ссылку, вы ее купили за 27 289 ₽ = $385.27 ? Или цена
была нормальная, а сейчас что-то произошло? - STM32любитeль(02.07.2025 01:55,
)
- где вы берете такой курс? - Ralex(02.07.2025 11:05)
- Напишите сюда пж какую цену вам показывает этой платы в рублях и
долларах. - STM32любитeль(Вчера, 23:09,
)
- $57.27 на их официальном сайте Бoмж(1 знак., Сегодня, 00:36, ссылка)
- А на Aliexpress сколько? - STM32любитeль(Сегодня, 06:32,
)
- А на Aliexpress сколько? - STM32любитeль(Сегодня, 06:32,
- $57.27 на их официальном сайте Бoмж(1 знак., Сегодня, 00:36, ссылка)
- Напишите сюда пж какую цену вам показывает этой платы в рублях и
долларах. - STM32любитeль(Вчера, 23:09,
- где вы берете такой курс? - Ralex(02.07.2025 11:05)
- Спасибо за ссылку, вы ее купили за 27 289 ₽ = $385.27 ? Или цена
была нормальная, а сейчас что-то произошло? - STM32любитeль(02.07.2025 01:55,
- Ali klen(1 знак., 02.07.2025 01:21, ссылка)
- Где покупали NUCLEO-N657X0-Q и почём. Дайте плз ссылку. - STM32любитeль(02.07.2025 00:23,