Тесты ARM Cortex A8: может ли кто-нибудь помочь мне разобраться в этих цифрах?

Я работаю над написанием нескольких алгоритмов DSP реального времени на Android, поэтому я решил запрограммировать ARM прямо в сборке, чтобы максимально оптимизировать все и сделать математику максимально легкий. Сначала я получал тесты скорости, которые не имели большого смысла, поэтому я начал читать об опасностях конвейера, возможностях двойной проблемы и так далее. Меня все еще озадачивают некоторые цифры, которые я получаю, поэтому я публикую их здесь в надежде, что кто-то сможет пролить свет на то, почему я получаю то, что получаю. В частности, меня интересует, почему NEON требует разного времени для выполнения вычислений с разными типами данных, даже если он утверждает, что выполняет каждую операцию ровно за один цикл. Мои выводы заключаются в следующем.

Я использую очень простой цикл для тестирования производительности и провожу его в течение 2 000 000 итераций. Вот моя функция:

hzrd_test:

    @use received argument an number of iterations in a loop
    mov r3 , r0

    @come up with some simple values
    mov r0, #1
    mov r1, #2

    @Initialize some NEON registers (Q0-Q11)
    vmov.32 d0, r0, r1
    vmov.32 d1, r0, r1
    vmov.32 d2, r0, r1

    ...

    vmov.32 d21, r0, r1
    vmov.32 d22, r0, r1
    vmov.32 d23, r0, r1

hzrd_loop:

    @do some math
    vadd.s32 q0, q0, q1
    vadd.s32 q1, q0, q1
    vadd.s32 q2, q0, q1
    vadd.s32 q3, q0, q1
    vadd.s32 q4, q0, q1
    vadd.s32 q5, q0, q1
    vadd.s32 q6, q0, q1
    vadd.s32 q7, q0, q1
    vadd.s32 q8, q0, q1
    vadd.s32 q9, q0,s q1
    vadd.s32 q10, q0, q1
    vadd.s32 q11, q0, q1

    @decrement loop counter, branch to loop again or return
    subs r3, r3, #1
    bne hzrd_loop

    @return
    mov r0, r3
    mov pc, lr

Обратите внимание на операцию вычисления и тип данных, указанные как сложение вектора ( vadd ) и 32-битное int со знаком ( s32 ). Эта операция завершается в течение определенного времени (см. Таблицу результатов ниже).Согласно этот документ ARM Cortex-A8 и следующие страницы, почти все элементарные арифметические операции в NEON должны выполняться за один цикл, но вот что я получаю:

vmul.f32 ~62ms
vmul.u32 ~125ms
vmul.s32 ~125ms

vadd.f32 ~63ms
vadd.u32 ~29ms
vadd.s32 ~30ms

Я выполняю их, просто заменяя операции и типы данных всего в приведенном выше цикле. Есть ли причина, по которой vadd.u32 вдвое быстрее, чем vadd.f32 , а vmul.f32 вдвое быстрее, чем vmul.u32 ?

Ура! =)

5
задан Phonon 8 November 2011 в 17:04
поделиться