벡터화 컴파일러는 NEON 하드웨어 장치를 효율적으로 사용하여 C/C++ 코드를 병렬화할 수 있습니다. C 언어에는 병렬 동작을 지정하는 구문이 없지만 컴파일러에 다양한 힌트를 제공할 수 있습니다.
포인터 변수의 경우 정의할 때 "__restrict" 키워드를 추가할 수 있지만, 포인터가 가리키는 메모리 영역이 외부 포인터에 의해 참조 및 수정될 수 없도록 해야 합니다. 이는 포인터가 겹치는 영역을 처리하지 않도록 보장하는 효과가 있습니다. 기억의).
루프 수는 분명히 4 또는 8의 배수이며 컴파일러에서도 최적화를 위해 사용됩니다.
코드를 컴파일할 때 -O1 -ftree-Vectorize -mfpu=neon 옵션을 추가합니다.
샘플 코드:
#include <stdio.h>
int main(int argc, char *argv[])
{
int arr[8] = {1,2,3,4,5,6,7,8};
for(int i = 0; i < 8; i++) {
arr[i] *= 3;
}
for(int i = 0; i < 8; i++) {
printf("%d\n", arr[i]);
}
return 0;
}
분해(V로 시작하는 명령어는 NEON 명령어입니다):
00010408 <main>:
10408: e92d4070 push {r4, r5, r6, lr}
1040c: e24dd020 sub sp, sp, #32
10410: e1a0c00d mov ip, sp
10414: e59fe05c ldr lr, [pc, #92] ; 10478 <main+0x70>
10418: e8be000f ldm lr!, {r0, r1, r2, r3}
1041c: e8ac000f stmia ip!, {r0, r1, r2, r3}
10420: e89e000f ldm lr, {r0, r1, r2, r3}
10424: e88c000f stm ip, {r0, r1, r2, r3}
10428: f2c04053 vmov.i32 q10, #3 ; 0x00000003
1042c: f46d2adf vld1.64 {d18-d19}, [sp :64]
10430: f26229f4 vmul.i32 q9, q9, q10
10434: f44d2adf vst1.64 {d18-d19}, [sp :64]
10438: eddd0b04 vldr d16, [sp, #16]
1043c: eddd1b06 vldr d17, [sp, #24]
10440: f26009f4 vmul.i32 q8, q8, q10
10444: edcd0b04 vstr d16, [sp, #16]
10448: edcd1b06 vstr d17, [sp, #24]
1044c: e1a0400d mov r4, sp
10450: e28d6020 add r6, sp, #32
10454: e59f5020 ldr r5, [pc, #32] ; 1047c <main+0x74>
10458: e4941004 ldr r1, [r4], #4
1045c: e1a00005 mov r0, r5
10460: ebffffa0 bl 102e8 <printf@plt>
10464: e1560004 cmp r6, r4
10468: 1afffffa bne 10458 <main+0x50>
1046c: e3a00000 mov r0, #0
10470: e28dd020 add sp, sp, #32
10474: e8bd8070 pop {r4, r5, r6, pc}
10478: 000104f0 .word 0x000104f0
1047c: 00010510 .word 0x00010510