<?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 Sorry for the delayed reply. in OpenCL* for CPU</title>
    <link>https://community.intel.com/t5/OpenCL-for-CPU/GPU-float16-memory-access-efficiency/m-p/1063432#M4256</link>
    <description>&lt;P&gt;Sorry for the delayed reply.&lt;/P&gt;

&lt;P&gt;In general, the compiler does a good job of optimizing memory I/O.&amp;nbsp; In some quick experiments with the SimpleOptimizations performance was close for float, float4, and float8.&amp;nbsp; As expected, the kernels based on vector types were faster.&amp;nbsp; Performance with float16 was slower than expected.&amp;nbsp;&lt;/P&gt;

&lt;P&gt;experiment&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; kernel runtime (ms)&lt;/P&gt;

&lt;OL&gt;
	&lt;LI&gt;float&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3390&lt;/LI&gt;
	&lt;LI&gt;float4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3215&lt;/LI&gt;
	&lt;LI&gt;float8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3020&lt;/LI&gt;
	&lt;LI&gt;float16&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4215&lt;/LI&gt;
&lt;/OL&gt;

&lt;P&gt;(Run on i5-4570, Linux Media Server Studio 2015 R6)&lt;/P&gt;

&lt;P&gt;Investigating now.&amp;nbsp; Will get back to you soon with more info.&lt;/P&gt;</description>
    <pubDate>Wed, 30 Dec 2015 20:44:20 GMT</pubDate>
    <dc:creator>Jeffrey_M_Intel1</dc:creator>
    <dc:date>2015-12-30T20:44:20Z</dc:date>
    <item>
      <title>GPU float16 memory access efficiency</title>
      <link>https://community.intel.com/t5/OpenCL-for-CPU/GPU-float16-memory-access-efficiency/m-p/1063431#M4255</link>
      <description>&lt;P&gt;According to &lt;A href="https://software.intel.com/en-us/node/540447"&gt;https://software.intel.com/en-us/node/540447,&lt;/A&gt; code like that below is inefficient as each work item in a subgroup (SIMD width) touches a different cache line (and only reads 4 bytes from each).&lt;/P&gt;

&lt;PRE class="brush:cpp;"&gt;__global int*   myArray = ...;
int x;
x = myArray[ get_global_id(0) * 16 ];&lt;/PRE&gt;

&lt;P&gt;However, what happens when you access 16-wide vectors instead? Will the compiler issue a 64-byte wide memory read per work item thus reading a full cache line per access, or will it treat each vector component individually, resulting in the same reduced memory bandwidth?&lt;/P&gt;

&lt;PRE class="brush:cpp;"&gt;__global float16*   myArray = ...;
float16 x;
x = myArray[ get_global_id(0) ];&lt;/PRE&gt;</description>
      <pubDate>Wed, 23 Dec 2015 17:29:21 GMT</pubDate>
      <guid>https://community.intel.com/t5/OpenCL-for-CPU/GPU-float16-memory-access-efficiency/m-p/1063431#M4255</guid>
      <dc:creator>Georg_K_</dc:creator>
      <dc:date>2015-12-23T17:29:21Z</dc:date>
    </item>
    <item>
      <title>Sorry for the delayed reply.</title>
      <link>https://community.intel.com/t5/OpenCL-for-CPU/GPU-float16-memory-access-efficiency/m-p/1063432#M4256</link>
      <description>&lt;P&gt;Sorry for the delayed reply.&lt;/P&gt;

&lt;P&gt;In general, the compiler does a good job of optimizing memory I/O.&amp;nbsp; In some quick experiments with the SimpleOptimizations performance was close for float, float4, and float8.&amp;nbsp; As expected, the kernels based on vector types were faster.&amp;nbsp; Performance with float16 was slower than expected.&amp;nbsp;&lt;/P&gt;

&lt;P&gt;experiment&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; kernel runtime (ms)&lt;/P&gt;

&lt;OL&gt;
	&lt;LI&gt;float&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3390&lt;/LI&gt;
	&lt;LI&gt;float4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3215&lt;/LI&gt;
	&lt;LI&gt;float8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 3020&lt;/LI&gt;
	&lt;LI&gt;float16&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 4215&lt;/LI&gt;
&lt;/OL&gt;

&lt;P&gt;(Run on i5-4570, Linux Media Server Studio 2015 R6)&lt;/P&gt;

&lt;P&gt;Investigating now.&amp;nbsp; Will get back to you soon with more info.&lt;/P&gt;</description>
      <pubDate>Wed, 30 Dec 2015 20:44:20 GMT</pubDate>
      <guid>https://community.intel.com/t5/OpenCL-for-CPU/GPU-float16-memory-access-efficiency/m-p/1063432#M4256</guid>
      <dc:creator>Jeffrey_M_Intel1</dc:creator>
      <dc:date>2015-12-30T20:44:20Z</dc:date>
    </item>
    <item>
      <title>Hi Georg,</title>
      <link>https://community.intel.com/t5/OpenCL-for-CPU/GPU-float16-memory-access-efficiency/m-p/1063433#M4257</link>
      <description>&lt;P&gt;Hi Georg,&lt;/P&gt;

&lt;P&gt;The optimal data type for our architecture is typically float4 (or uint4, int4, or char16 or uchar16 - basically 16 bytes from a work-item). Occasionally, you may get good performance from float8 (typically, very short kernels as you can see above). Using float16 is not recommended for couple of reasons:&lt;/P&gt;

&lt;P&gt;1) you typically end up using way too much private memory per work item so you will be bumped from SIMD32 to SIMD16 compilation for small kernels and from SIMD16 to SIMD8 for larger ones and if you are already at SIMD8, there is a high probability of spills to global memory, which you don't want;&lt;/P&gt;

&lt;P&gt;2) You will probably end up with too much compute per hardware thread (typically you have 8 threads per EU (Ivy Bridge) or 7 threads per EU (Haswell and Broadwell and Skylake) and only 2 SIMD4 FPUs per EU, so when using float16, you are most likely will be compute limited for any reasonably sized kernel.&lt;/P&gt;

&lt;P&gt;3) You are reading/writing much more data that the optimal spot of the architecture, so you are definitely bandwidth limited with float16.&lt;/P&gt;

&lt;P&gt;With float16, your kernel will probably compile SIMD16 (it is very short) or SIMD8. In the first case you end up reading 16 * 4 * 16 = 1024 bytes of data from a hardware thread - 4 times the optimal amount (16 cache lines worth of data, as opposed to 4 or 8, which is optimal).&lt;/P&gt;</description>
      <pubDate>Wed, 06 Jan 2016 23:39:24 GMT</pubDate>
      <guid>https://community.intel.com/t5/OpenCL-for-CPU/GPU-float16-memory-access-efficiency/m-p/1063433#M4257</guid>
      <dc:creator>Robert_I_Intel</dc:creator>
      <dc:date>2016-01-06T23:39:24Z</dc:date>
    </item>
    <item>
      <title>Hi Robert and Jeffrey,</title>
      <link>https://community.intel.com/t5/OpenCL-for-CPU/GPU-float16-memory-access-efficiency/m-p/1063434#M4258</link>
      <description>&lt;P&gt;Hi Robert and Jeffrey,&lt;/P&gt;

&lt;P&gt;Thanks for the detailed answer.&lt;/P&gt;

&lt;P&gt;Re 1) I am working with a Broadwell/Iris 6100 system at the moment. My understanding is that Gen8 GPUs have 28 KiB of general purpose registers per Execution Unit, 4 KiB per hardware thread. In SIMD8 mode each work item should thus have 128 dwords of private memory available (64 and 32 dwords for SIMD16 and SIMD32, respectively). Of those I imagine some will be used for work item IDs, kernel args and other internal values (I seem to recall this from the Beignet source code), so the number available to user code is somewhat smaller. Still, using a couple of float16 values will only cause spilling if there's a significant amount of other live registers.&lt;/P&gt;

&lt;P&gt;While I indeed intend to be careful not to spill to global memory, I don't think the documentation mentions any drawbacks of using the register space fully (since registers are assigned to threads on a fixed basis there is no register/thread occupancy trade-off as on other GPUs).&lt;/P&gt;

&lt;P&gt;By the way, I think it's a shame the Intel OpenCL implementation seems to have no way of forcing a certain SIMD width, or, in fact, no way of directly using an EU thread as a single work item. While the cl_intel_subgroups extension does much to allow work items of the same subgroup to communicate efficiently, my kernel code would actually be quite a bit more readable (and possibly more efficient) if written as mostly using float16 operations on arrays spanning the whole 4 KiB of private memory.&lt;/P&gt;

&lt;P&gt;Re 2) Whether I choose to use float16 or a smaller type will have no bearing on the computation my kernel needs to perform nor on the number of values I need to read from memory. The question is whether I will have to rearrange the values in memory to get good utilisation of bandwidth or whether it's ok to process 16 consecutive values in a single work item.&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;

&lt;P&gt;Ultimately my question comes down to whether the compiler can generate load ops that are effectively transposed, i.e. instead of generating a sequence of N loads which each read one float per work item in parallel, generate a sequence of N-wide loads, one per work item.&lt;/P&gt;

&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 11 Jan 2016 15:50:00 GMT</pubDate>
      <guid>https://community.intel.com/t5/OpenCL-for-CPU/GPU-float16-memory-access-efficiency/m-p/1063434#M4258</guid>
      <dc:creator>Georg_K_</dc:creator>
      <dc:date>2016-01-11T15:50:00Z</dc:date>
    </item>
    <item>
      <title>Georg,</title>
      <link>https://community.intel.com/t5/OpenCL-for-CPU/GPU-float16-memory-access-efficiency/m-p/1063435#M4259</link>
      <description>&lt;P&gt;Georg,&lt;/P&gt;

&lt;P&gt;Very interesting question: took me a while to research :)&lt;/P&gt;

&lt;P&gt;I took the following code:&lt;/P&gt;

&lt;PRE class="brush:cpp;"&gt;kernel void foo(global float* in, global float* out) { 
&amp;nbsp;int i = get_global_id(0);

&amp;nbsp;float f = in&lt;I&gt;;
&amp;nbsp;float temp = 0.5f * f;
&amp;nbsp;out&lt;I&gt; = temp;
}

kernel void foo2(global float2* in, global float2* out) { 
&amp;nbsp;int i = get_global_id(0);

&amp;nbsp;float2 f = in&lt;I&gt;;
&amp;nbsp;float2 temp = 0.5f * f;
&amp;nbsp;out&lt;I&gt; = temp;
}

kernel void foo4(global float4* in, global float4* out) { 
&amp;nbsp;int i = get_global_id(0);

&amp;nbsp;float4 f = in&lt;I&gt;;
&amp;nbsp;float4 temp = 0.5f * f;
&amp;nbsp;out&lt;I&gt; = temp;
}

kernel void foo8(global float8* in, global float8* out) { 
&amp;nbsp;int i = get_global_id(0);

&amp;nbsp;float8 f = in&lt;I&gt;;
&amp;nbsp;float8 temp = 0.5f * f;
&amp;nbsp;out&lt;I&gt; = temp;
}

kernel void foo16(global float16* in, global float16* out) { 
&amp;nbsp;int i = get_global_id(0);

&amp;nbsp;float16 f = in&lt;I&gt;;
&amp;nbsp;float16 temp = 0.5f * f;
&amp;nbsp;out&lt;I&gt; = temp;
}&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/PRE&gt;

&lt;P&gt;and compiled it with our latest Intel SDK for OpenCL Applications:&lt;/P&gt;

&lt;BLOCKQUOTE&gt;
	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;OpenCL Intel(R) Graphics device was found!&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Device name: Intel(R) Iris(TM) Graphics 6100&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Device version: OpenCL 2.0 &lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Device vendor: Intel(R) Corporation&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Device profile: FULL_PROFILE&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;fcl build 1 succeeded.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;fcl build 2 succeeded.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;bcl build succeeded.&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;foo info:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Maximum work-group size: 256&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Compiler work-group size: (0, 0, 0)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Local memory size: 0&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Preferred multiple of work-group size: 32&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Minimum amount of private memory: 0&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;foo2 info:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Maximum work-group size: 256&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Compiler work-group size: (0, 0, 0)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Local memory size: 0&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Preferred multiple of work-group size: 32&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Minimum amount of private memory: 0&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;foo4 info:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Maximum work-group size: 256&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Compiler work-group size: (0, 0, 0)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Local memory size: 0&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Preferred multiple of work-group size: 32&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Minimum amount of private memory: 0&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;foo8 info:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Maximum work-group size: 256&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Compiler work-group size: (0, 0, 0)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Local memory size: 0&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Preferred multiple of work-group size: 16&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Minimum amount of private memory: 0&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;foo16 info:&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Maximum work-group size: 256&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Compiler work-group size: (0, 0, 0)&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Local memory size: 0&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Preferred multiple of work-group size: 16&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Minimum amount of private memory: 0&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;

	&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;&lt;FONT face="Consolas" size="2"&gt;Build succeeded!&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;

&lt;P&gt;&lt;FONT face="Consolas" size="2"&gt;To summarize: float, float2, and float4 versions were compiled SIMD32 and float8 and float16 versions were compiled SIMD16. Now, lets look at the assembly generated by the read instruction in all those kernels:&lt;/FONT&gt;&lt;/P&gt;

&lt;P&gt;foo:&lt;/P&gt;

&lt;PRE class="brush:plain;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M0)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r27&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r19&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x4146EFF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M8)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r28&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r21&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x4146EFF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M16)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r29&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r23&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x4146EFF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M24)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r30&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r25&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x4146EFF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&lt;/PRE&gt;

&lt;P&gt;In SIMD32 mode, two send instructions act as one, so we actually have two sends here. One register holds 8 floats, so it takes 4 registers to keep the values of one read.&lt;/P&gt;

&lt;P&gt;foo2:&lt;/P&gt;

&lt;PRE class="brush:plain;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M0)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r31&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r19&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x4246CFF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M8)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r23&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r21&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x4246CFF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M16)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r35&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r25&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x4246CFF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M24)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r29&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r27&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x4246CFF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&lt;/PRE&gt;

&lt;P&gt;Though those sends (loads) look similar to foo kernel, each actually loads two registers worth of data, so one instruction (two sends) loads 4 registers, for a total of 8 registers for the code above. If you look at the full assembly listing, you will notice several moves to get the loaded data in a shape acceptable to multiply instruction. Nevertheless, the sends are the expensive ones.&lt;/P&gt;

&lt;P&gt;foo4:&lt;/P&gt;

&lt;PRE class="brush:plain;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M0)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r19&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r15&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x44460FF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M8)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r23&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r17&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x44460FF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M16)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r31&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r27&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x44460FF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M24)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r35&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r29&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x44460FF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&lt;/PRE&gt;

&lt;P&gt;Again, four sends here (actually two SIMD32 instructions), but now we load 8 registers worth of data. The number of moves to prepare data for multiplication increases even more, but the number of sends stays the same - we just load more data.&lt;/P&gt;

&lt;P&gt;foo8:&lt;/P&gt;

&lt;PRE class="brush:plain;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M0)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r50&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r72&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x44460FF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M8)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r76&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r74&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x44460FF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M0)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r58&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r68&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x44460FF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M8)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r64&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r70&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x44460FF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&lt;/PRE&gt;

&lt;P&gt;Now were are in SIMD16 land, so we have 4 sends that are 4 SIMD16 instructions. Each loads 4 registers worth of data. In fact, the amount of data here is similar to the previous case, it is just that we have 2X data per SIMD lane.&lt;/P&gt;

&lt;P&gt;foo16:&lt;/P&gt;

&lt;PRE class="brush:plain;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M0)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r82&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r120&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x44460FF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M8)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r18&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r122&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x44460FF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M0)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r90&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r14&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x44460FF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M8)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r10&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r16&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x44460FF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M0)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r98&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r6&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x44460FF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M8)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r124&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r8&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x44460FF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M0)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r106&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r116&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x44460FF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; send&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (8|M8)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r112&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; r118&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0xC&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0x44460FF&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // id:2
&lt;/PRE&gt;

&lt;P&gt;Now, we finally get to double the number of sends. Still each send loads 4 registers worth of data.&amp;nbsp;Each register will have 8 floats. And there will be a whole lot of moves to prepare data for multiplication (compiler generates 16 mul operations, each working on two registers worth of floats).&lt;/P&gt;

&lt;P&gt;So, each send is capable of bringing a maximum of 128 bytes, or 32 floats to the thread. For more efficient loading you will need to look into bulk media loads, which are part of intel simd shuffle extension.&lt;/P&gt;

&lt;P&gt;Note that in terms of efficiency of loading the data float4 in SIMD32 case and float8 in SIMD16 case are equivalent.So you could say that we are sort of doing N-wide loads.&lt;/P&gt;</description>
      <pubDate>Wed, 13 Jan 2016 01:57:23 GMT</pubDate>
      <guid>https://community.intel.com/t5/OpenCL-for-CPU/GPU-float16-memory-access-efficiency/m-p/1063435#M4259</guid>
      <dc:creator>Robert_I_Intel</dc:creator>
      <dc:date>2016-01-13T01:57:23Z</dc:date>
    </item>
  </channel>
</rss>

