Closed steve1515 closed 3 years ago
After doing some research, the issue here seems to be that I have a 64-bit OS. I was able to use the PLATFORM=armv8-generic
options to compile successfully.
A question remains though...
make help
seems to indicate that compiling this way will use main CPU for FFT as opposed to the PLATFORM=rpiv2
option that indicates that the BCM VideoCore will be used for FFT. Is there a way to still use the VideoCore in 64-bit architectures? Will there be a performance penalty?
I can't answer your question as to a workaround to enable use of VideoCore after compiling, though I'm curious to see the answer. Because my 32-bit RPI 4 also needed to be compiled with armv8-generic. However, I can say there are limitations in what the CPU can do. It just depends on your use case and rtl_airband config. e.g. fft_size, sample_rate, channels and devices. I've been CPU limited in a few things I wanted to try. These CPU limits will apply even more so to the RPI 3. That said, for certain uses, you can enable multithreaded flags. See the wiki for when both of those can be used.
multiple_demod_threads = true; multiple_output_threads = true;
@steve1515 -mfpu=neon-vfpv4
and -mfloat-abi=hard
options are not available for aarch64 architecture because these features are always enabled on that arch. Just remove these options from the makefile and try again.
@dlpwx VideoCore in RPi4 is different than in earlier RPi generations, hence it is not supported in rtl_airband. armv8-generic
is the only way to go on this platform.
@szpajder When I remove those two options, I get the following error:
cc1plus: error: unknown value ‘armv7-a’ for ‘-march’
cc1plus: note: valid arguments are: armv8-a armv8.1-a armv8.2-a armv8.3-a armv8.4-a armv8.5-a native; did you mean ‘armv8-a’?
If I then change the -march
to either -march=armv8-a+crc
or -march=armv8-a
, I get the following error:
rtl_airband.cpp:22:2: error: #error Broadcom VideoCore support can only be enabled on ARM builds
22 | #error Broadcom VideoCore support can only be enabled on ARM builds
| ^~~~~
make: *** [<builtin>: rtl_airband.o] Error 1
This might be something that needs to be fixed in the source code. It looks like __arm__
is only defined in 32-bit architectures, so the way the code is written (line 22 of rtl_airband.cpp) will only allow VideoCore with 32-bit systems.
If I simply comment out that check on line 22 and compile with -march=armv8-a+crc
or -march=armv8-a
, I then get the following errors:
ubuntu@ubuntu:~/rtlsdr-airband/RTLSDR-Airband-3.2.1$ make PLATFORM=rpiv2 NFM=1
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math -DNFM -DWITH_RTLSDR -c -o rtl_airband.o rtl_airband.cpp
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math -DNFM -DWITH_RTLSDR -c -o input-common.o input-common.cpp
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math -DNFM -DWITH_RTLSDR -c -o input-helpers.o input-helpers.cpp
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math -DNFM -DWITH_RTLSDR -c -o input-file.o input-file.cpp
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math -DNFM -DWITH_RTLSDR -c -o output.o output.cpp
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math -DNFM -DWITH_RTLSDR -c -o config.o config.cpp
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math -DNFM -DWITH_RTLSDR -c -o util.o util.cpp
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math -DNFM -DWITH_RTLSDR -c -o mixer.o mixer.cpp
make -C hello_fft
make[1]: Entering directory '/home/ubuntu/rtlsdr-airband/RTLSDR-Airband-3.2.1/hello_fft'
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math -DNFM -DWITH_RTLSDR -I.. -c -o mailbox.o mailbox.c
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math -DNFM -DWITH_RTLSDR -I.. -c -o gpu_fft.o gpu_fft.c
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math -DNFM -DWITH_RTLSDR -I.. -c -o gpu_fft_twiddles.o gpu_fft_twiddles.c
gpu_fft_twiddles.c: In function ‘float* twiddles_step_16(double, float*, double)’:
gpu_fft_twiddles.c:70:39: warning: unused parameter ‘two_pi’ [-Wunused-parameter]
70 | static float *twiddles_step_16(double two_pi, float *out, double theta) {
| ~~~~~~~^~~~~~
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math -DNFM -DWITH_RTLSDR -I.. -c -o gpu_fft_shaders.o gpu_fft_shaders.c
g++ -O3 -g -Wall -Wextra -DSYSCONFDIR=\"/usr/local/etc\" -DDEBUG=0 -DUSE_BCM_VC -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux -march=armv8-a -ffast-math -DNFM -DWITH_RTLSDR -I.. -c -o gpu_fft_base.o gpu_fft_base.c
gpu_fft_base.c: In function ‘unsigned int gpu_fft_base_exec_direct(GPU_FFT_BASE*, int)’:
gpu_fft_base.c:65:16: warning: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Wsign-compare]
65 | for (q=0; q<num_qpus; q++) { // Launch shader(s)
| ~^~~~~~~~~
gpu_fft_base.c:72:50: warning: comparison of integer expressions of different signedness: ‘unsigned int’ and ‘int’ [-Wsign-compare]
72 | if (((base->peri[V3D_SRQCS]>>16) & 0xff) == num_qpus) break; // All done?
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~
gpu_fft_base.c:54:17: warning: unused variable ‘t’ [-Wunused-variable]
54 | unsigned q, t;
| ^
ar r hello_fft.a mailbox.o gpu_fft.o gpu_fft_twiddles.o gpu_fft_shaders.o gpu_fft_base.o
ar: creating hello_fft.a
make[1]: Leaving directory '/home/ubuntu/rtlsdr-airband/RTLSDR-Airband-3.2.1/hello_fft'
as -o rtl_airband_neon.o rtl_airband_neon.s
rtl_airband_neon.s: Assembler messages:
rtl_airband_neon.s:26: Error: unknown pseudo-op: `.fpu'
rtl_airband_neon.s:30: Error: unknown mnemonic `push' -- `push {r4-r12,lr}'
rtl_airband_neon.s:31: Error: unknown mnemonic `vpush' -- `vpush {d4-d15}'
rtl_airband_neon.s:36: Error: operand 1 must be an integer register -- `ldr r4,[r0]'
rtl_airband_neon.s:37: Error: operand 1 must be an integer register -- `ldr r0,[r0,#4]'
rtl_airband_neon.s:39: Error: operand 1 must be an integer register -- `ldrb r5,[r1]'
rtl_airband_neon.s:40: Error: operand 1 must be an integer register -- `ldrb r6,[r1,#1]'
rtl_airband_neon.s:41: Error: operand 1 must be an integer register -- `ldrb r7,[r1,#2]'
rtl_airband_neon.s:42: Error: operand 1 must be an integer register -- `ldrb r8,[r1,#3]'
rtl_airband_neon.s:43: Error: operand 1 must be an integer register -- `ldrb r9,[r1,#4]'
rtl_airband_neon.s:44: Error: operand 1 must be an integer register -- `ldrb r10,[r1,#5]'
rtl_airband_neon.s:45: Error: operand 1 must be an integer register -- `ldrb r11,[r1,#6]'
rtl_airband_neon.s:46: Error: operand 1 must be an integer register -- `ldrb r12,[r1,#7]'
rtl_airband_neon.s:50: Error: operand 1 must be an integer register -- `ldr r5,[r3,r5,LSL#2]'
rtl_airband_neon.s:51: Error: operand 1 must be an integer register -- `ldr r6,[r3,r6,LSL#2]'
rtl_airband_neon.s:52: Error: operand 1 must be an integer register -- `ldr r7,[r3,r7,LSL#2]'
rtl_airband_neon.s:53: Error: operand 1 must be an integer register -- `ldr r8,[r3,r8,LSL#2]'
rtl_airband_neon.s:54: Error: operand 1 must be an integer register -- `ldr r9,[r3,r9,LSL#2]'
rtl_airband_neon.s:55: Error: operand 1 must be an integer register -- `ldr r10,[r3,r10,LSL#2]'
rtl_airband_neon.s:56: Error: operand 1 must be an integer register -- `ldr r11,[r3,r11,LSL#2]'
rtl_airband_neon.s:57: Error: operand 1 must be an integer register -- `ldr r12,[r3,r12,LSL#2]'
rtl_airband_neon.s:59: Error: unknown mnemonic `vldmia' -- `vldmia r2!,{d8-d11}'
rtl_airband_neon.s:60: Error: operand 1 must be an integer or stack pointer register -- `add r1,r1,#8'
rtl_airband_neon.s:62: Error: unknown mnemonic `vmov' -- `vmov d4,r5,r6'
rtl_airband_neon.s:63: Error: unknown mnemonic `vmov' -- `vmov d5,r7,r8'
rtl_airband_neon.s:64: Error: unknown mnemonic `vmov' -- `vmov d6,r9,r10'
rtl_airband_neon.s:65: Error: unknown mnemonic `vmov' -- `vmov d7,r11,r12'
rtl_airband_neon.s:66: Error: unknown mnemonic `pld' -- `pld [r1,#16]'
rtl_airband_neon.s:67: Error: unknown mnemonic `vmul.f32' -- `vmul.f32 q6,q2,q4'
rtl_airband_neon.s:68: Error: unknown mnemonic `vmul.f32' -- `vmul.f32 q7,q3,q5'
rtl_airband_neon.s:69: Error: unknown mnemonic `pld' -- `pld [r2,#8]'
rtl_airband_neon.s:70: Error: operand 1 must be an integer register -- `ldrb r5,[r1]'
rtl_airband_neon.s:71: Error: operand 1 must be an integer register -- `ldrb r6,[r1,#1]'
rtl_airband_neon.s:72: Error: operand 1 must be an integer register -- `ldrb r7,[r1,#2]'
rtl_airband_neon.s:73: Error: operand 1 must be an integer register -- `ldrb r8,[r1,#3]'
rtl_airband_neon.s:74: Error: operand 1 must be an integer register -- `ldrb r9,[r1,#4]'
rtl_airband_neon.s:75: Error: operand 1 must be an integer register -- `ldrb r10,[r1,#5]'
rtl_airband_neon.s:76: Error: operand 1 must be an integer register -- `ldrb r11,[r1,#6]'
rtl_airband_neon.s:77: Error: operand 1 must be an integer register -- `ldrb r12,[r1,#7]'
rtl_airband_neon.s:78: Error: unknown mnemonic `vstmia' -- `vstmia r0!,{q6-q7}'
rtl_airband_neon.s:79: Error: operand 1 must be an integer register -- `subs r4,r4,#1'
rtl_airband_neon.s:82: Error: unknown mnemonic `vpop' -- `vpop {d4-d15}'
rtl_airband_neon.s:83: Error: unknown mnemonic `pop' -- `pop {r4-r12,pc}'
make: *** [<builtin>: rtl_airband_neon.o] Error 1
Maybe it's not possible to use the VideoCore on 64-bit on a RPi 3?
Right, I forgot to mention that the assembly code for DSP operations which is enabled together with VC support works only on 32-bit arches.
In this case I suggest switching to a 32-bit OS.
I just came to report that I've now tried with 32-bit Ubuntu and VC support. I'm now get about 25% CPU usage vs. the 50% I was getting without VC support in the 64-bit Ubuntu.
Describe your environment
make
options used to build the program: $ make PLATFORM=rpiv2 NFM=1What happened? When compiling the 2 errors below occur.
What you expected to happen? Compile without errors.
Steps to Reproduce