<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic I should probably mention in OpenCL* for CPU</title>
    <link>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124315#M5568</link>
    <description>I should probably mention that the problem only exists when the code is run on GPU, on CPU the problem doesn't exist.

&lt;BLOCKQUOTE&gt;Allan M. wrote:&lt;BR /&gt; &lt;P&gt;170-360ms equates to a huge amount of &lt;EM&gt;potential&lt;/EM&gt; GFLOPS... unless you're actually memory bound.&lt;/P&gt;
 &lt;/BLOCKQUOTE&gt;

That is the runtime for the whole kernel the loop takes on the 170ms runtime about 60-80ms. Only thing I can think is the fact that unrolling the loop causes huge amount of cache misses because I don't see any other way why it would take 4-5 times longer. I'm not too familiar with the structure of Intel's integrated GPU and their caches. 

&lt;BLOCKQUOTE&gt;Allan M. wrote:&lt;BR /&gt; &lt;P&gt;The inner loop looks like it would map well to 16 threads (work-items)..&lt;/P&gt;
 &lt;/BLOCKQUOTE&gt;

Unfortunately not possible. I'm already using 3 dimensions and while I could change the structure to use two the memory handling wouldn't allow braking the kernel down any further.</description>
    <pubDate>Thu, 12 May 2016 18:42:49 GMT</pubDate>
    <dc:creator>Joose_S_</dc:creator>
    <dc:date>2016-05-12T18:42:49Z</dc:date>
    <item>
      <title>Weird performance with loop unrolling</title>
      <link>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124311#M5564</link>
      <description>&lt;P&gt;I have a kernel that calculates motion vectors with fullsearch and mse. There is weird performance issues with the following loop:&lt;/P&gt;

&lt;PRE class="brush:cpp;"&gt;  #define W_SIZE 16
  for (int y = 0; y != W_SIZE; y++)
  {
    for(uint x = 0; x != W_SIZE; x++)
    {
      float img1 = img1V[x + (y)*W_SIZE];
      float img2 = img2V[x + (localID&amp;amp;VALUE) + (y+ localID/W_SIZE)*W_SIZE*2];
      float img3 = img3V[x + (y)*W_SIZE];
      float result = img1-img2;
      float result2 = img3-img2;
      diffs += result*result;
      diffs2 += result2 * result2;
    }
  }&lt;/PRE&gt;

&lt;P&gt;The whole kernel takes about 360ms to execute. However if I change the outer loop to iterate from -1 to W_SIZE-1 and at 1 to y inside the loop (or any other values for that matter) execution time drops to 170ms.&lt;/P&gt;

&lt;P&gt;Only reason I've come up with for this issue is loop unrolling that only happens when the loop iterates from 0 to scalar but using #pragma unroll has pracically no impact to performance. I tried making one loop instead of two nested ones but it still took 360ms to finish.&lt;/P&gt;

&lt;P&gt;Does anybody have any idea what is causing this and if there is any way to fix it?&lt;/P&gt;</description>
      <pubDate>Thu, 12 May 2016 14:28:58 GMT</pubDate>
      <guid>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124311#M5564</guid>
      <dc:creator>Joose_S_</dc:creator>
      <dc:date>2016-05-12T14:28:58Z</dc:date>
    </item>
    <item>
      <title>I don't recall if #pragma</title>
      <link>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124312#M5565</link>
      <description>&lt;P&gt;I don't recall if #pragma unroll actually works in Intel's OpenCL compiler. &amp;nbsp;Anyone?&lt;/P&gt;

&lt;P&gt;You could always try manually unrolling your inner loop.&lt;/P&gt;

&lt;P&gt;Example:&lt;/P&gt;

&lt;PRE class="brush:cpp;"&gt;#define W_SIZE 16

#define UNROLL_16()  \
  UNROLL_X(0)        \
  UNROLL_X(1)        \
  UNROLL_X(2)        \
  UNROLL_X(3)        \
  UNROLL_X(4)        \
  UNROLL_X(5)        \
  UNROLL_X(6)        \
  UNROLL_X(7)        \
  UNROLL_X(8)        \
  UNROLL_X(9)        \
  UNROLL_X(10)       \
  UNROLL_X(11)       \
  UNROLL_X(12)       \
  UNROLL_X(13)       \
  UNROLL_X(14)       \
  UNROLL_X(15)

for (int y=0; y&amp;lt;W_SIZE; y++)
  {
#undef  UNROLL_X
#define UNROLL_X(x)                                                     \
    float img1    = img1V[x + y * W_SIZE];                              \
    float img2    = img2V[x + (localID &amp;amp; VALUE) + (y + localID / W_SIZE) * W_SIZE * 2]; \
    float img3    = img3V[x + y * W_SIZE];                              \
    float result  = img1 - img2;                                        \
    float result2 = img3 - img2;                                        \
    diffs        += result  * result;                                   \
    diffs2       += result2 * result2;

    UNROLL_16();
  }
&lt;/PRE&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 12 May 2016 16:32:50 GMT</pubDate>
      <guid>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124312#M5565</guid>
      <dc:creator>allanmac1</dc:creator>
      <dc:date>2016-05-12T16:32:50Z</dc:date>
    </item>
    <item>
      <title>It's not the inner loop that</title>
      <link>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124313#M5566</link>
      <description>It's not the inner loop that's the problem but the outer. It is getting unrolled properly and the #pragma unroll had an effect on it but the compiler optimised it the best way without doing anything special about it. 

It seems I'm loosing performance when the outer loop is unrolled.</description>
      <pubDate>Thu, 12 May 2016 16:39:29 GMT</pubDate>
      <guid>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124313#M5566</guid>
      <dc:creator>Joose_S_</dc:creator>
      <dc:date>2016-05-12T16:39:29Z</dc:date>
    </item>
    <item>
      <title>170-360ms equates to a huge</title>
      <link>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124314#M5567</link>
      <description>&lt;P&gt;170-360ms equates to a huge amount of &lt;EM&gt;potential&lt;/EM&gt; GFLOPS... unless you're actually memory bound.&lt;/P&gt;

&lt;P&gt;Have you verified your memory transactions are "coalesced" and some multiple of 64 bytes?&lt;/P&gt;

&lt;P&gt;The inner loop looks like it would map well to 16 threads (work-items).&lt;/P&gt;</description>
      <pubDate>Thu, 12 May 2016 18:22:34 GMT</pubDate>
      <guid>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124314#M5567</guid>
      <dc:creator>allanmac1</dc:creator>
      <dc:date>2016-05-12T18:22:34Z</dc:date>
    </item>
    <item>
      <title>I should probably mention</title>
      <link>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124315#M5568</link>
      <description>I should probably mention that the problem only exists when the code is run on GPU, on CPU the problem doesn't exist.

&lt;BLOCKQUOTE&gt;Allan M. wrote:&lt;BR /&gt; &lt;P&gt;170-360ms equates to a huge amount of &lt;EM&gt;potential&lt;/EM&gt; GFLOPS... unless you're actually memory bound.&lt;/P&gt;
 &lt;/BLOCKQUOTE&gt;

That is the runtime for the whole kernel the loop takes on the 170ms runtime about 60-80ms. Only thing I can think is the fact that unrolling the loop causes huge amount of cache misses because I don't see any other way why it would take 4-5 times longer. I'm not too familiar with the structure of Intel's integrated GPU and their caches. 

&lt;BLOCKQUOTE&gt;Allan M. wrote:&lt;BR /&gt; &lt;P&gt;The inner loop looks like it would map well to 16 threads (work-items)..&lt;/P&gt;
 &lt;/BLOCKQUOTE&gt;

Unfortunately not possible. I'm already using 3 dimensions and while I could change the structure to use two the memory handling wouldn't allow braking the kernel down any further.</description>
      <pubDate>Thu, 12 May 2016 18:42:49 GMT</pubDate>
      <guid>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124315#M5568</guid>
      <dc:creator>Joose_S_</dc:creator>
      <dc:date>2016-05-12T18:42:49Z</dc:date>
    </item>
    <item>
      <title>Quote:Joose S. wrote:I should</title>
      <link>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124316#M5569</link>
      <description>&lt;P&gt;&lt;/P&gt;&lt;BLOCKQUOTE&gt;Joose S. wrote:&lt;BR /&gt;&lt;SPAN style="font-size: 1em; line-height: 1.5;"&gt;I should probably mention that the problem only exists when the code is run on GPU, on CPU the problem doesn't exist.&lt;/SPAN&gt;&lt;SPAN style="font-size: 1em; line-height: 1.5;"&gt;&lt;/SPAN&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;&lt;/P&gt;

&lt;P&gt;&lt;SPAN style="font-size: 1em; line-height: 1.5;"&gt;Based on your code snippet, it's unclear to me whether or not your kernel has been explicitly converted into "work item" and "work group" form that can take advantage of "wide" SIMT/SIMD architectures like Intel's IGP or a discrete GPU.&lt;/SPAN&gt;&lt;/P&gt;

&lt;P&gt;Forgive me if you've already done this. :)&lt;/P&gt;</description>
      <pubDate>Thu, 12 May 2016 19:00:00 GMT</pubDate>
      <guid>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124316#M5569</guid>
      <dc:creator>allanmac1</dc:creator>
      <dc:date>2016-05-12T19:00:00Z</dc:date>
    </item>
    <item>
      <title>Quote:Allan M. wrote:</title>
      <link>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124317#M5570</link>
      <description>&lt;BLOCKQUOTE&gt;Allan M. wrote:&lt;BR /&gt; &lt;P&gt;&lt;STRONG class="quote-header"&gt;Quote:&lt;/STRONG&gt;&lt;/P&gt;&lt;BLOCKQUOTE class="quote-msg quote-nest-1 odd"&gt;&lt;DIV class="quote-author"&gt;&lt;EM class="placeholder"&gt;Joose S.&lt;/EM&gt; wrote:&lt;/DIV&gt;I should probably mention that the problem only exists when the code is run on GPU, on CPU the problem doesn't exist.&lt;/BLOCKQUOTE&gt;&lt;P&gt;&lt;/P&gt;
&lt;P&gt;Based on your code snippet, it's unclear to me whether or not your kernel has been explicitly converted into "work item" and "work group" form that can take advantage of "wide" SIMT/SIMD architectures like Intel's IGP or a discrete GPU.&lt;/P&gt;
&lt;P&gt;Forgive me if you've already done this. :)&lt;/P&gt;
 &lt;/BLOCKQUOTE&gt;

Yeah I have split the work load and omitted most of the code. I'm just interested why the "optimasation" runtime/compiler does makes the code significantly slower. And what I can to do prevent it. For some reason giving clBuildProgram  -cl-opt-disable flag did nothing for execute time so I am at kinda loss here.</description>
      <pubDate>Thu, 12 May 2016 19:52:34 GMT</pubDate>
      <guid>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124317#M5570</guid>
      <dc:creator>Joose_S_</dc:creator>
      <dc:date>2016-05-12T19:52:34Z</dc:date>
    </item>
    <item>
      <title>Hi Joose,</title>
      <link>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124318#M5571</link>
      <description>&lt;P&gt;Hi Joose,&lt;/P&gt;

&lt;P&gt;What processor, OS, driver version are you using? Could you give the whole kernel and maybe a small reproducer? I am not aware of any way to stop loop unrolling on the GPU, it typically happens automatically: I will ask our driver folks.&lt;/P&gt;</description>
      <pubDate>Sat, 14 May 2016 00:23:48 GMT</pubDate>
      <guid>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124318#M5571</guid>
      <dc:creator>Robert_I_Intel</dc:creator>
      <dc:date>2016-05-14T00:23:48Z</dc:date>
    </item>
    <item>
      <title>Quote:Robert I. (Intel) wrote</title>
      <link>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124319#M5572</link>
      <description>&lt;P&gt;&lt;/P&gt;&lt;BLOCKQUOTE&gt;Robert I. (Intel) wrote:&lt;BR /&gt;&lt;P&gt;&lt;/P&gt;

&lt;P&gt;Hi Joose,&lt;/P&gt;

&lt;P&gt;What processor, OS, driver version are you using? Could you give the whole kernel and maybe a small reproducer? I am not aware of any way to stop loop unrolling on the GPU, it typically happens automatically: I will ask our driver folks.&lt;/P&gt;

&lt;P&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;&lt;/P&gt;

&lt;P&gt;i5-4590, Windows 7 Enterprise, Intel drivers version 10.18.14.4280&lt;/P&gt;

&lt;P&gt;I've attached files that should reproduce the problem.&lt;/P&gt;

&lt;P&gt;Changing the outer loop from y = 0; y != W_SIZE to y = 1; y!= 17, and subtracting 1 from y everywhere it's used greatly increases the performance.&lt;/P&gt;</description>
      <pubDate>Mon, 16 May 2016 11:54:51 GMT</pubDate>
      <guid>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124319#M5572</guid>
      <dc:creator>Joose_S_</dc:creator>
      <dc:date>2016-05-16T11:54:51Z</dc:date>
    </item>
    <item>
      <title>I tried changing the loop to</title>
      <link>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124320#M5573</link>
      <description>&lt;P&gt;I tried changing the loop to use vectors to&lt;/P&gt;

&lt;PRE class="brush:cpp;"&gt;  __local float* maskStart = img2V+(localID&amp;amp;VALUE)+(localID&amp;amp;(~VALUE))*2;
  for(int x = 0; x != 16; x++)
  {
    float16 img1 = vload16(x,img1V);         
    float16 img2 = vload16(2*(x), maskStart);
    float16 img3 = vload16(x, img3V);
    float16 result = img1-img2;
    float16 result2 = img3-img2;
    diffs += result*result;
    diffs2 += result2 * result2;
  }&lt;/PRE&gt;

&lt;P&gt;Which got the execution time down to 220ms but again doing&lt;/P&gt;

&lt;PRE class="brush:cpp;"&gt;  __local float* maskStart = img2V+(localID&amp;amp;VALUE)+(localID&amp;amp;(~VALUE))*2;
  for(int x = 1; x != 17; x++)
  {
    float16 img1 = vload16(x-1,img1V);         
    float16 img2 = vload16(2*(x-1), maskStart);
    float16 img3 = vload16(x-1, img3V);
    float16 result = img1-img2;
    float16 result2 = img3-img2;
    diffs += result*result;
    diffs2 += result2 * result2;
  }&lt;/PRE&gt;

&lt;P&gt;gets it down to 170ms.&lt;/P&gt;</description>
      <pubDate>Mon, 16 May 2016 13:37:37 GMT</pubDate>
      <guid>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124320#M5573</guid>
      <dc:creator>Joose_S_</dc:creator>
      <dc:date>2016-05-16T13:37:37Z</dc:date>
    </item>
    <item>
      <title>Hi Joose,</title>
      <link>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124321#M5574</link>
      <description>&lt;P&gt;Hi Joose,&lt;/P&gt;

&lt;P&gt;This is what I got from compiler team:&lt;/P&gt;

&lt;P style="margin: 0in 0in 0pt;"&gt;&lt;SPAN style="color:#1F497D"&gt;&lt;FONT face="Calibri" size="3"&gt;We support the OpenCL 2.0 loop unroll attribute, which can be used to control loop unrolling.&amp;nbsp; Search the spec for: &lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="font-family:&amp;quot;Courier New&amp;quot;;color:black"&gt;&lt;FONT size="3"&gt;__attribute__((opencl_unroll_hint(n)))&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN style="color:#1F497D"&gt;&lt;FONT face="Calibri" size="3"&gt; .&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;

&lt;P style="margin: 0in 0in 0pt;"&gt;&amp;nbsp;&lt;/P&gt;

&lt;P style="margin: 0in 0in 0pt;"&gt;&lt;SPAN style="color:#1F497D"&gt;&lt;FONT face="Calibri" size="3"&gt;That being said, there are a couple of caveats:&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;

&lt;P style="margin: 0in 0in 0pt;"&gt;&lt;SPAN style="color:#1F497D"&gt;&lt;FONT face="Calibri" size="3"&gt;- It doesn’t have any effect on older drivers, where we parsed the attribute but otherwise ignored it.&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;

&lt;P style="margin: 0in 0in 0pt;"&gt;&lt;SPAN style="color:#1F497D"&gt;&lt;FONT face="Calibri" size="3"&gt;- It should work fine on SKL+ on any of the 15.45 drivers.&amp;nbsp; Even today, it won’t work on any of the BDW drivers built from the 15.40 branch, but e.g. Linux BDW drivers built from mainline will work fine.&amp;nbsp; Crazy, I know.&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;

&lt;P&gt;&lt;SPAN style="font-size:11.0pt;font-family:&amp;quot;Calibri&amp;quot;,sans-serif;mso-fareast-font-family:
Calibri;mso-fareast-theme-font:minor-latin;mso-bidi-font-family:&amp;quot;Times New Roman&amp;quot;;
color:#1F497D;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:
AR-SA"&gt;- Last time I checked we only parsed the attribute for OpenCL 2.0 compiles (with –cl-std=CL2.0), but not for OpenCL 1.2 compiles.&amp;nbsp; &lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 16 May 2016 16:56:33 GMT</pubDate>
      <guid>https://community.intel.com/t5/OpenCL-for-CPU/Weird-performance-with-loop-unrolling/m-p/1124321#M5574</guid>
      <dc:creator>Robert_I_Intel</dc:creator>
      <dc:date>2016-05-16T16:56:33Z</dc:date>
    </item>
  </channel>
</rss>

