<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Dec 19, 2013 at 4:36 PM, Renato Golin <span dir="ltr"><<a href="mailto:renato.golin@linaro.org" target="_blank">renato.golin@linaro.org</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="im"><div class="gmail_extra"><div class="gmail_quote">On 19 December 2013 08:50, suyog sarda <span dir="ltr"><<a href="mailto:sardask01@gmail.com" target="_blank">sardask01@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div class="gmail_extra"><div class="gmail_quote"><div>It may seem that total number of cycles are more or less same for single vmla and vmul+vadd. However, when vmul+vadd combination is used instead of vmla, then intermediate results will be generated which needs to be stored in memory for future access. This will lead to lot of load/store ops being inserted which degrade performance. Correct me if i am wrong on this, but my observation till date have shown this. <br>

</div></div></div></div></div></blockquote><div></div></div><br></div></div><div class="gmail_extra">VMLA.F can be either NEON or VFP on A series and the encoding will determine which will be used. In assembly files, the difference is mainly the type vs. the registers used.</div>

<div class="gmail_extra"><br></div><div class="gmail_extra">The problem we were trying to avoid a long time ago was well researched by Evan Cheng and it has shown that there is a pipeline stall between two sequential VMLAs (possibly due to the need of re-use of some registers) and this made code much slower than a sequence of VMLA+VMUL+VADD.</div>

<div class="gmail_extra"><br></div><div class="gmail_extra">Also, please note that, as accurate as cycle counts go, according to the A9 manual, one VFP VMLA takes almost as long as a pair of VMUL+VADD to provide the results, so a sequence of VMUL+VADD might be faster, in some contexts or cores, than half the sequence of VMLAs.</div>

<div class="gmail_extra"><br></div><div class="gmail_extra">As Tim and David said and I agree, without hard data, anything we say might be used against us. ;)</div><div class="gmail_extra"><br></div></div></blockquote><div>
<br><br><div class="gmail_extra">Sorry folks, i didn't specify the actual test case and results in detail previously. The details are as follows :<br><br></div><div class="gmail_extra">Test case name : llvm/projects/test-suite/SingleSource/Benchmarks/Misc/matmul_f64_4x4.c  - This is a 4x4 matrix multiplication, we can make small changes to make it a 3x3 matrix multiplication for making things simple to understand .<br>
</div><div class="gmail_extra"><br></div><div class="gmail_extra">clang version : trunk version (latest as of today 19 Dec 2013)<br></div><div class="gmail_extra">GCC version : 4.5 (i checked with 4.8 as well)<br><br></div>
<div class="gmail_extra">flags passed to both gcc and clang : -march=armv7-a  -mfloat-abi=softfp  -mfpu=vfpv3-d16  -mcpu=cortex-a8<br></div><div class="gmail_extra">Optimization level used : O3<br><br></div><div class="gmail_extra">
No vmla instruction emitted by clang but GCC happily emits it.<br></div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra">This was tested on real hardware. Time taken for a 4x4 matrix multiplication:<br>
<br></div><div class="gmail_extra">clang : ~14 secs<br></div><div class="gmail_extra">gcc : ~9 secs<br><br><br>Time taken for a 3x3 matrix multiplication:<br><br><div class="gmail_extra">clang : ~6.5 secs<br></div>gcc : ~5 secs<br>
</div><div class="gmail_extra"><br><br></div><div class="gmail_extra">when flag -mcpu=cortex-a8 is changed to -mcpu=cortex-a15, clang emits vmla instructions (gcc emits by default)<br><br></div><div class="gmail_extra">Time for 4x4 matrix multiplication :<br>
<br></div><div class="gmail_extra">clang : ~8.5 secs<br></div><div class="gmail_extra">GCC : ~9secs<br><br></div><div class="gmail_extra">Time for matrix multiplication :<br><br></div><div class="gmail_extra">clang : ~3.8 secs<br>
</div><div class="gmail_extra">GCC : ~5 secs<br clear="all"></div><div class="gmail_extra"><br></div><div class="gmail_extra">Please
 let me know if i am missing something. (-ffast-math option doesn't help
 in this case.) On examining assembly code for various scenarios above, i
 concluded what i have stated above regarding more load/store ops.<br></div>Also, as stated by Renato - "there is a pipeline stall between two sequential VMLAs (possibly due to 
the need of re-use of some registers) and this made code much slower 
than a sequence of VMLA+VMUL+VADD" , when i use -mcpu=cortex-a15 as option, clang emits vmla instructions back to back(sequential) . Is there something different with cortex-a15 regarding pipeline stalls, that we are ignoring back to back vmla hazards?<br>
   <br></div><div>-- <br>With regards,<br>Suyog Sarda <br></div></div><br></div></div>