clock_gettime is slow

..on the pandaboard. I just measured it , and each call to clock_gettime(CLOCK_MONOTONIC) takes approximately 800ns . On a core 2 quad it takes 27ns , and it has also a muuuuchh better resolution that the ARM one, which has a resolution of 1/32787th second. Using CLOCK_REALTIME or whatever does not improve the timings.

NEON optimized single precision sin / cos / exp and log

This is a translation of the SSE version to ARM NEON intrinsics. Je profite de l'occasion pour dire que : the official ARM NEON documentation is quite shitty.

ARM Cortex A9 Peak FLOPS

I have just measured the peak gflops performance for the cortex A9, using this snippet of code:



@@ int ni = 65536*16;

   __asm__ volatile("mov  r5, #0\n"
                    "vdup.f32 q0, r5\n"
                    "vdup.f32 q1, r5\n"
                    "vdup.f32 q2, r5\n"
                    "vdup.f32 q3, r5\n"
                    "vdup.f32 q4, r5\n"
                    "mov r5, %0\n"
                    "1:\n"
                    "vmla.f32 q0, q0, q0\n"
                    "vmla.f32 q1, q1, q1\n"
                    "vmla.f32 q2, q2, q2\n"
                    "vmla.f32 q3, q3, q3\n"
                    "vmla.f32 q4, q4, q4\n"
                    "subs r5, r5, #1\n"
                    "bne 1b\n" : : "r"(ni) : "q0", "q1", "q2", "q3", "q4", "r5");@@

Each loop does (4 float per vec) * (5 vmla operations) * (2 flop per vlma) = 40 flop, repeated ni times. The result for the 1GHz cortex A9 of my pandaboard: 3.99919 GFlops , which was quite expected but it is always good to see a confirmation. Reducing the number of VMLA (fused multiply add) in the loop results in a lower performance (the vlma latency is 5 cycles if I recall correctly, so that is also expected). Using separate VMUL and VADD operations produces 2 GFlops instead of 4.

Interestingly, replacing the five VLMA on size-4 vectors by 10 VLMA on size-2 vector produces almost the peak 4 GFlops: 3.64 GFlops.

Assembleur ARM

Vous serez heureux d'apprendre que je commence à masteuriser l'assembleur ARM ! gcc a quand même un peu de mal à pondre du code optimal pour NEON , et le cortex-A9 n'est quand même pas un foudre de guerre. Donc au lieu de passer mon temps à rearranger le code C un peu au pif pour qu'en sortie gcc recrache de l'asm bien gaulé, je me suis décidé a faire directement de l'asm. Un bon exemple se trouve dans les sources de ffmpeg, il y a même une FFT dont je suis sûr qu'elle dépote les platypus.

Et le fait est que les instructions NEON sont largement mieux foutues que l'espece de truc bancal qu'est SSE, avec ses 8 pauvres registres 128 bits, ses instructions qui ecrasent toujours une des deux operandes, et son shuffle dont chaque utilisation donne l'impression d'être en train de résoudre un problème de rubik-cube. NEON c'est 16 registres 128 bits, qui peuvent etre manipulés comme 32 registres 64-bits, des instructions avec deux registres sources et un registre destination (comme altivec). Des instructions plutot claires et non ambigues (contrairements aux shuffle/unpacklo/unpackhi/movehl,movelh etc de sse). Des instructions load/store pas chiantes avec l'alignement , par defaut elles marchent sur des données non alignées sur 16-bytes, mais si on est sûr de l'alignement on peut leur donner un hint qui permet de gagner quelque chose comme 10% de vitesse. Pas sûr qu'on puisse encore considerer tout ça comme du RISC, par exemple : vld1 {q0,q1}, [r0,:256]! charge d'un coup 32 octets dans les deux registres q0 et q1 , avec un hint d'alignement sur 256-bits, et post-incrémente r0 d'autant. Du coup, sur les calculs qui sont assez soft avec la mémoire j'arrive à approcher les 2 GFlops sur un coeur de cortex A9 à 1GHz ce qui commence a être assez satisfaisant.

Pandaboard

Depuis une semaine j'ai une Pandaboard ! Contrairement au toshiba AC100 avec son tegra2 qui pue, celle-ci est basée sur le OMAP4 de texas instruments, qui a une unité SIMD NEON, comme tous les autres cortex A9 et le futur tegra 3. Le cpu dual core fonctionne a 1GHz, la carte mesure 10x12cm , actuellement elle tourne sous ubuntu 11.04 et consomme 4W (mais je ne suis pas sur du tout de la precision du wattmetre). En gros c'est de la boulette.