<div dir="ltr">Thanks, Ayal!<div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jun 16, 2016 at 7:15 AM, Zaks, Ayal <span dir="ltr"><<a href="mailto:ayal.zaks@intel.com" target="_blank">ayal.zaks@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">





<div lang="EN-US" link="blue" vlink="purple">
<div>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">Some thoughts:<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">o To determine the VF for a loop with mixed data sizes, choosing the smallest ensures each vector register used is full, choosing the largest will minimize the
 number of vector registers used. Which one’s better, or some size in between, depends on the target’s costs for the vector operations, availability of registers and possibly control/memory divergence and trip count. “This is a question of cost modeling” and
 its associated compile-time, but in general good vectorization of loops with mixed data sizes is expected to be important, especially when larger scopes are vectorized. BTW, SLP followed this a year ago:
<a href="http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20150706/286110.html" target="_blank">
http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20150706/286110.html</a><u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u> </span></p></div></div></blockquote><div><br></div><div>Yes, I agree completely.</div><div>The approach we have right now is that availability of registers is a hard upper bound, and I'm not planning on changing that (e.g. by modeling spill cost.) at the moment.</div><div><br></div><div>I'm not too worried about the compile time impact. I haven't measured it yet, but one thing that may mitigate this is the fact that postponing interleaving until the legalizer will result in smaller IR coming out of the vectorizer. So the increased compile-time cost of the TTI queries may be offset by the decreased amount of work for post-vectorizer IR passes and pre-legalization ISel. Anyway, this is all idle talk right now, as you and Nadav said, it needs to be measured.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple"><div><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">o As for increasing VF beyond maximize-bandwidth, one could argue that a vectorizer should focus on tapping the SIMD capabilities of the target, up to maximize-bandwidth,
 and that its vectorized loop should later be subject to a separate independent unroller/interleaver pass. One suggestion, regardless, is to use the term “unroll-and-jam”, which traditionally applies to loops containing control-flow and nested loops but is
 quite clear for innermost loops too, instead of the overloaded term “interleaving”. Admittedly loop vectorization conceptually applies unroll-and-jam followed by packetization into vectors, so why unroll-and-jam twice. As noted, the considerations for best
 unroll factor are different from those of best VF for optimal usage of SIMD capabilities. Indeed representing in LLVM-IR a loop with vectors longer than maximize-bandwidth looks more appealing than replicating its ‘legal’ vectors, easier produced by the vectorizer
 than by an unroll-and-jam pass. BTW, taken to the extreme, one could vectorize to the full trip count of the loop, as in
<a href="http://impact.crhc.illinois.edu/shared/Papers/tr2014.mxpa.pdf" target="_blank">http://impact.crhc.illinois.edu/shared/Papers/tr2014.mxpa.pdf</a><a name="m_-2176794871463996435__MailEndCompose">, where memory spatial locality is deemed more important to optimize than register usage.<u></u><u></u></a></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u> </span></p></div></div></blockquote><div><br></div><div>"Why unroll-and-jam twice" is precisely the motivation behind increasing VF beyond maximize-bandwidth. :-)</div><div>Both getting good code from the legalizer and getting good cost modeling for illegal types are required to increase VF up to choosing the smallest scalar type. And if that works out, then going beyond maximize-bandwidth seems like it should require fairly little additional work. I think once we go beyond maximize-bandwidth, and assume the legalizer will split things back up, the consideration for the best unroll factor and the best VF becomes essentially the same, since increasing the VF, in effect, increases the unroll factor.</div><div><br></div><div>It's possible that we'll need two different cost estimates, one up to max-bandwidth, and one beyond max-bandwidth - and in this case, I'm not sure the exercise is worthwhile.</div><div>In any case, I mostly see this is as a bonus, what's really important to me is getting maximize-bandwidth to work well.</div><div><br></div><div>As to the terminology - I agree "unroll-and-jam" is the correct technical term, but it's not currently used in the vectorizer, and I wanted to keep the terminology here consistent with the code.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple"><div><p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">Ayal.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u> <u></u></span></p>
<p class="MsoNormal"><a name="m_-2176794871463996435______replyseparator"></a><b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif">From:</span></b><span style="font-size:11.0pt;font-family:"Calibri",sans-serif"> Michael Kuperstein [mailto:<a href="mailto:mkuper@google.com" target="_blank">mkuper@google.com</a>]
<br>
<b>Sent:</b> Thursday, June 16, 2016 10:42<br>
<b>To:</b> Nadav Rotem <<a href="mailto:nadav.rotem@me.com" target="_blank">nadav.rotem@me.com</a>><br>
<b>Cc:</b> Hal Finkel <<a href="mailto:hfinkel@anl.gov" target="_blank">hfinkel@anl.gov</a>>; Zaks, Ayal <<a href="mailto:ayal.zaks@intel.com" target="_blank">ayal.zaks@intel.com</a>>; Demikhovsky, Elena <<a href="mailto:elena.demikhovsky@intel.com" target="_blank">elena.demikhovsky@intel.com</a>>; Adam Nemet <<a href="mailto:anemet@apple.com" target="_blank">anemet@apple.com</a>>; Sanjoy Das <<a href="mailto:sanjoy@playingwithpointers.com" target="_blank">sanjoy@playingwithpointers.com</a>>; James Molloy <<a href="mailto:james.molloy@arm.com" target="_blank">james.molloy@arm.com</a>>; Matthew Simpson <<a href="mailto:mssimpso@codeaurora.org" target="_blank">mssimpso@codeaurora.org</a>>;
 Sanjay Patel <<a href="mailto:spatel@rotateright.com" target="_blank">spatel@rotateright.com</a>>; Chandler Carruth <<a href="mailto:chandlerc@google.com" target="_blank">chandlerc@google.com</a>>; David Li <<a href="mailto:davidxl@google.com" target="_blank">davidxl@google.com</a>>; Wei Mi <<a href="mailto:wmi@google.com" target="_blank">wmi@google.com</a>>; Dehao Chen <<a href="mailto:dehao@google.com" target="_blank">dehao@google.com</a>>; Cong Hou <<a href="mailto:congh@google.com" target="_blank">congh@google.com</a>>; Llvm Dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>><br>
<b>Subject:</b> Re: [RFC] Allow loop vectorizer to choose vector widths that generate illegal types<u></u><u></u></span></p><div><div class="h5">
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<div>
<p class="MsoNormal">Hi Nadav,<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">Thanks a lot for the feedback!<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<p class="MsoNormal">Of course we need to explore this with numbers. Not just in terms of the performance vs. compile-time, but in general in terms of the performance benefit. For now, I'm just trying to get a feel for whether people think this sounds like
 a reasonable idea. As I wrote in the original email, we already have this under a flag (it was added by Cong last year). But it will be hard to get reliable performance numbers without first having the cost model provide better-quality answers at the higher
 vectorization factors. <u></u><u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I didn't mean that we should be duplicating every optimization the SelectionDAG makes. Of course the cost model is only a rough approximation. What I do want the (generic) cost model to do, however, is provide a more-or-less precise approximation
 of legalization costs. To be concrete, <a href="http://reviews.llvm.org/D21251" target="_blank">
http://reviews.llvm.org/D21251</a> is a first step in that direction. Do you think this is something the cost model should not be doing?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Regarding loop widening - see my email to Dibyendu for what I meant. For mixed-type loops, it really depends. Let's say you have a mixed-type loop, with i32 and i64, and 256-bit registers. Would the extra parallelism you get from vectorizing
 by 4 and interleaving be worth the throughput loss you suffer from not vectorizing the i32 operations by 8? It seems like this would depend heavily on the specific loop, and the proportion of i32 and i64 instructions. This is exactly the question I'd like
 to get the cost model to answer. Do you think this is not feasible? It shouldn't (I hope :-) ) require modeling every possible shuffle.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Thanks,<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  Michael<u></u><u></u></p>
</div>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">On Wed, Jun 15, 2016 at 11:24 PM, Nadav Rotem <<a href="mailto:nadav.rotem@me.com" target="_blank">nadav.rotem@me.com</a>> wrote:<u></u><u></u></p>
<blockquote style="border:none;border-left:solid #cccccc 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm">
<div>
<div>
<p class="MsoNormal">Hi Michael, <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Thank you for working on this. The loop vectorizer tries a bunch of different vectorization factors and stops at the widest word size mostly because of compile time concerns. On every vectorization factors that we check we have to scan
 all of the instructions in the loop and make multiple calls into TTI. If you decide to increase the VF enumeration space then you will linearly increase the compile time of the loop vectorizer. I think that it would be a good idea to explore this compile-time
 vs performance tradeoff with numbers. <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">The cost model is designed to be a fast approximation of SelectionDAG. We don't want to duplicate every optimization in SelectionDAG into the cost model because this would make the code model (and the optimizer) difficult to maintain. If
 the cost model does not represent an operation that you care about then you should add it to the cost tables. <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">I don't understand how selecting wide vectors would eliminate the need to have loop widening.  Loop widening happens to break data dependencies and allow more parallelism. If you have two independent arithmetic operations then they can
 go into different execution units, or to pipelined execution units. Your mixed-typed loops would cause a shuffle across registers (which we can't model well in the cost model, for obvious reasons) that will pack multiple lanes into a smaller vector and this
 would introduce a data dependency. <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Maybe you should start by increasing the enumeration space (by 2X, for example) under a flag and see if you get any performance gains. <u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><span style="color:#888888"><u></u> <u></u></span></p>
</div>
<div>
<p class="MsoNormal"><span style="color:#888888">-Nadav<u></u><u></u></span></p>
</div>
<div>
<p class="MsoNormal" style="margin-bottom:12.0pt"><br>
On Jun 15, 2016, at 03:48 PM, Michael Kuperstein <<a href="mailto:mkuper@google.com" target="_blank">mkuper@google.com</a>> wrote:<u></u><u></u></p>
</div>
<div>
<blockquote style="margin-top:5.0pt;margin-bottom:5.0pt">
<div>
<div>
<p class="MsoNormal">Hello,<br>
<br>
Currently the loop vectorizer will, by default, not consider vectorization factors that would make it generate types that do not fit into the target platform's vector registers. That is, if the widest scalar type in the scalar loop is i64, and the platform's
 largest vector register is 256-bit wide, we will not consider a VF above 4.<br>
<br>
We have a command line option (-mllvm -vectorizer-maximize-bandwidth), that will choose VFs for consideration based on the narrowest scalar type instead of the widest one, but I don't believe it has been widely tested. If anyone has had an opportunity to play
 around with it, I'd love to hear about the results.<br>
<br>
What I'd like to do is:<u></u><u></u></p>
<div>
<div>
<p class="MsoNormal">Step 1: Make -vectorizer-maximize-bandwidth the default. This should improve the performance of loops that contain mixed-width types.<br>
Step 2: Remove the artificial width limitation altogether, and base the vectorization factor decision purely on the cost model. This should allow us to get rid of the interleaving code in the loop vectorizer, and get interleaving for "free" from the legalizer
 instead.<u></u><u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">There are two potential road-blocks I see - the cost-model, and the legalizer. To make this work, we need to:<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">a) Model the cost of operations on illegal types better. Right now, what we get is sometimes completely ridiculous (e.g. see <a href="http://reviews.llvm.org/D21251" target="_blank">http://reviews.llvm.org/D21251</a>).<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">b) Make sure the cost model actually stops us when the VF becomes too large. This is mostly a question of correctly estimating the register pressure. In theory, that should not be a issue - we already rely on this estimate to choose the
 interleaving factor, so using the same logic to upper-bound the VF directly shouldn't make things worse.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">c) Ensure the legalizer is up to the task of emitting good code for overly wide vectors. I've talked about this with Chandler, and his opinion (Chandler, please correct me if I'm wrong) is that on x86, the legalizer is likely to be able
 to handle this. This may not be true for other platforms. So, I'd like to try to make this the default on a platform-by-platform basis, starting with x86.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">What do you think? Does this seem like a step in the right direction? Anything important I'm missing?<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">Thanks,<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal">  Michael<u></u><u></u></p>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div></div></div>
<p>---------------------------------------------------------------------<br>
Intel Israel (74) Limited</p>

<p>This e-mail and any attachments may contain confidential material for<br>
the sole use of the intended recipient(s). Any review or distribution<br>
by others is strictly prohibited. If you are not the intended<br>
recipient, please contact the sender and delete all copies.</p></div>

</blockquote></div><br></div></div></div>