Revital Eres revital.eres@linaro.org writes:
chain, so what makes the SMS version of it worse than the non-SMS version?
I attached the SMS dump file. The problematic loop is the one with "SMS succeeded 36 2" (there are three loops in total in this file). Due to these accumulators min ii is 36 which seems to cause SMS to take wrong decisions.
SMS iis 36 36 72 (rec_mii, mii, maxii)
OK, so the minimum ii comes from each dependency in the chain of 4 accumulations having a latency of 9 cycles. But the A9 TRM says:
If a multiply-accumulate follows a multiply or another multiply-accumulate, and depends on the result of that first instruction, then if the dependency between both instructions are of the same type and size, the processor uses a special multiplier accumulator forwarding. This special forwarding means the multiply instructions can issue back-to-back because the result of the first instruction in cycle 5 is forwarded to the accumulator of the second instruction in cycle 4. If the size and type of the instructions do not match, then Dd or Qd is required in cycle 3. This applies to combinations of the multiply-accumulate instructions VMLA, VMLS, VQDMLA, and VQDMLS, and the multiply instructions VMUL andVQDMUL.
So I think the problem is that successive VMLAs don't in fact have a latency of 9. However, this doesn't seem to be modelled in the ARM backend, either through bypasses or in a sched-reorder hook. In contrast, the A8 pipeline description has:
;; A multiply with a single-register result or an MLA, followed by an ;; MLA with an accumulator dependency, has its result forwarded so two ;; such instructions can issue back-to-back. (define_bypass 1 "cortex_a8_mul,cortex_a8_mla,cortex_a8_smulwy" "cortex_a8_mla" "arm_mac_accumulator_is_mul_result")
I'm not sure from the A9 description whether "following" means "immediately following", or whether gaps between instructions are allowed (and, in the latter case, whether the gap can be filled with arbitrary instructions, or whether restrictions apply, such as "anything but another NEON multiplication"). Ramana, do you know?
Anyway, I think this explains why the non-SMS loop executes more quickly than GCC expects, and why the SMS loop is slower than it needs to be. It might be worth comparing the two loops with -mtune=cortex-a8.
Richard