Part Number: TDA4VMXEVM
Hello all,
SUMMARY:
I've been benchmarking the J721EX board running the SDK auto Linux and OpenVX for C66 DSPs (TIOVX library). In summary, I've been observing at least one order of magnitude lower performance than I'd expect from datasheets and manuals.
TI MEASURED PERFORMANCE ANALYSIS:
Please consider the table at http://software-dl.ti.com/jacinto7/esd/processor-sdk-rtos-jacinto7/latest/exports/docs/tiovx/docs/user_guide/TIOVX_PERFORMANCE_J7ES_LINUX.html
The entry #80 for the Multiply OpenVX kernel states:
Index | Kernel | Variant | Frame Size (Pixels) | Graph Performance (msec) | Node Performance (msec) |
80 | Multiply | S16 x S16 = S16 | 640x480 (307200) | 4.057000 | 3.978000 |
This means that 307200 int16_t elements are multiplied by 307200 int16_t elements, one by one, and produces 307200 int16_t elements.
Then, I disassembled the released C66 firmware loaded by Linux:
~/psdk_rtos_auto_j7_06_01_01_12/c6000_7.4.24/bin/dis6x --all ~/psdk_rtos_auto_j7_06_01_01_12/vision_apps/out/J7/C66/SYSBIOS/release/vx_app_tirtos_linux_c6x_1.out > /tmp/c66.lst
And counted the number of cycles spent in the inner loop of VXLIB_multiply_i16s_i16s_o16s_core:
ad1e86d8 $C$L32: ad1e86d8 0d66 SPLOOP 3 ad1e86da 5947 || MV.L2X A18,B18 ad1e86dc ec081000 .fphead n, h, W, BU, nobr, nosat, 1100000b ad1e86e0 $C$L33: ad1e86e0 2ce7 SPMASK L1,L2 ad1e86e2 1581 ||^ ADD.L2X A19,8,B16 ad1e86e4 044c5765 || LDDW.D1T1 *A19++[2],A9:A8 ad1e86e8 024857e7 || LDDW.D2T2 *B18++[2],B5:B4 ad1e86ec 09490058 ||^ ADD.L1 8,A18,A18 ad1e86f0 02485764 LDDW.D1T1 *A18++[2],A5:A4 ad1e86f4 044057e6 LDDW.D2T2 *B16++[2],B9:B8 ad1e86f8 00004000 NOP 3 ad1e86fc e0280003 .fphead n, h, W, BU, nobr, nosat, 0000001b ad1e8700 12209032 DMPY2.M2X B5:B4,A9:A8,B7:B6:B5:B4 ad1e8704 12209030 DMPY2.M1X A5:A4,B9:B8,A7:A6:A5:A4 ad1e8708 00002000 NOP 2 ad1e870c 0310a01b PACK2.L2 B5,B4,B6 ad1e8710 0398eff2 || PACK2.S2 B7,B6,B7 ad1e8714 1440d033 DMPY2.M2X B7:B6,A17:A16,B11:B10:B9:B8 ad1e8718 0310a019 || PACK2.L1 A5,A4,A6 ad1e871c 0398eff0 || PACK2.S1 A7,A6,A7 ad1e8720 1440c030 DMPY2.M1 A7:A6,A17:A16,A11:A10:A9:A8 ad1e8724 ac66 SPMASK D2 ad1e8726 39d7 ||^ MV.D2X A3,B17 ad1e8728 00430001 SPMASK D1 ad1e872c 018d0940 ||^ ADD.D1 A3,0x8,A3 ad1e8730 0a21201b PACK2.L2 B9,B8,B20 ad1e8734 0aa96ff2 || PACK2.S2 B11,B10,B21 ad1e8738 0a4457c7 STDW.D2T2 B21:B20,*B17++[2] ad1e873c e0400004 .fphead n, l, W, BU, nobr, nosat, 0000010b ad1e8740 0a212019 || PACK2.L1 A9,A8,A20 ad1e8744 0aa96ff0 || PACK2.S1 A11,A10,A21 ad1e8748 0c034001 SPKERNEL 3,0 ad1e874c 0a0c5744 || STDW.D1T1 A21:A20,*A3++[2] ad1e8750 $C$L34:
Between SPLOOP and SPKERNEL, there are 20 cycles, and each DMPY2 processes 4 elements, resulting in 8 multiplications per loop iteration (the 3rd and 4th DMPY2 are applying a constant scaling factor). Therefore, as a 1st order of approximation, each element takes 20/8 = 2.5 cycles to be processed. Compared to http://software-dl.ti.com/jacinto7/esd/processor-sdk-rtos-jacinto7/latest/exports/docs/vxlib_c66x_1_1_4_0/docs/VXLIB_c66x_TestReport.html, my estimation is 5 times bigger than the best measured result of 0.5 cycles/element. I could not find a better inner loop in the disassembled firmware.
In total, the 307200 multiplications should take 2.5*307200 = 768000 cycles.
We can finally estimate the DSP clock frequency as (768000 cycles) / (3.978 ms) = 193061840 cycles/s = 193 MHz.
The TDA4VM datasheet states that the C66 DSP can be clocked up to 1.35 GHz, so this means that the evaluation kit DSP is largely underclocked by a factor of 7.
MY FP IMPLEMENTATION:
I've implemented and benchmarked FP kernels (with SIMD FP multiply QMPYSP) myself and observed a consistent underclocking factor of 10. In other words, the performance I'd expect is consistently 10x lower, even when processing multiplications of 5120 x 3840 image planes = 79 MB.
Some hypotheses I can imagine are:
1) DSP is underclocked
2) L2 HW prefetcher in C66 not initialized
3) DDR bus not at full speed 1866 MHz
Could someone please help here?
Thanks,
Fernando A. Endo