<?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 Array notation surprisingly slow in Software Archive</title>
    <link>https://community.intel.com/t5/Software-Archive/Array-notation-surprisingly-slow/m-p/991587#M27899</link>
    <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;i made a unusual discovery today. I wanted to compare the speed of a program using array notation with the speed of a program without it. The program adds two arrays of 1,000,000 integers one thousand times and then reports the result (see below).&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;[cpp] int main(int argc, char ** argv) { &lt;BR /&gt; int array1[1000000];&lt;BR /&gt; int array2[1000000];&lt;BR /&gt; int a = 1;&lt;BR /&gt; for (int i = 0; i &amp;lt; 1000000; i++) {&lt;BR /&gt; array1&lt;I&gt; = a; &lt;BR /&gt; array2&lt;I&gt; = a;&lt;BR /&gt; }&lt;BR /&gt; for (int j = 0; j &amp;lt; 1000; j++) { &lt;BR /&gt; for (int i = 0; i &amp;lt; 1000000; i++) { &lt;BR /&gt; array1&lt;I&gt; += array2&lt;I&gt;; } &lt;BR /&gt; } &lt;BR /&gt; cout &amp;lt;&amp;lt; array1[0]&amp;lt;&amp;lt; endl; [/cpp]&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;The second program is its array-notation equivalent&lt;/P&gt;
&lt;P&gt;[cpp] int main(int argc, char ** argv) {&lt;BR /&gt; int array1[1000000];&lt;BR /&gt; int array2[1000000];&lt;BR /&gt; array1[0:1000000] = a;&lt;BR /&gt; array2[0:1000000] = a;&lt;BR /&gt; for (int j = 0; j &amp;lt; 1000; j++) {&lt;BR /&gt; array1[0:1000000] += array2[0:1000000];&lt;BR /&gt; }&lt;BR /&gt; cout &amp;lt;&amp;lt; array1[0]&amp;lt;&amp;lt; endl;&lt;BR /&gt; [/cpp]&lt;/P&gt;
&lt;P&gt;Without any optimization upon compilation, the first program (without the array-notation) took about 2.9 seconds and the second program took about 1.9 seconds. If i use optimization level -O3, the first program takes 0.6 seconds and the second program still takes 1.2 second. This is double the time the first program uses.&lt;/P&gt;
&lt;P&gt;Obviously, the two for-loops of the first program get vectorized, when using the -O3 option. Still, i would have thought, that the array-notation version was at least as fast. Did i miss something there? Maybe there is a bug somewhere when trying to optimize array-notation-code, so it generates less efficient code.If not - what do have to do to get the array-notation as fast as the "normal" code?&lt;/P&gt;
&lt;P&gt;I used a recent version of the cilkplus-branch of the gcc (a few days old) and a Core i7.&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Thu, 13 Sep 2012 11:40:25 GMT</pubDate>
    <dc:creator>leifblaese</dc:creator>
    <dc:date>2012-09-13T11:40:25Z</dc:date>
    <item>
      <title>Array notation surprisingly slow</title>
      <link>https://community.intel.com/t5/Software-Archive/Array-notation-surprisingly-slow/m-p/991587#M27899</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;i made a unusual discovery today. I wanted to compare the speed of a program using array notation with the speed of a program without it. The program adds two arrays of 1,000,000 integers one thousand times and then reports the result (see below).&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;[cpp] int main(int argc, char ** argv) { &lt;BR /&gt; int array1[1000000];&lt;BR /&gt; int array2[1000000];&lt;BR /&gt; int a = 1;&lt;BR /&gt; for (int i = 0; i &amp;lt; 1000000; i++) {&lt;BR /&gt; array1&lt;I&gt; = a; &lt;BR /&gt; array2&lt;I&gt; = a;&lt;BR /&gt; }&lt;BR /&gt; for (int j = 0; j &amp;lt; 1000; j++) { &lt;BR /&gt; for (int i = 0; i &amp;lt; 1000000; i++) { &lt;BR /&gt; array1&lt;I&gt; += array2&lt;I&gt;; } &lt;BR /&gt; } &lt;BR /&gt; cout &amp;lt;&amp;lt; array1[0]&amp;lt;&amp;lt; endl; [/cpp]&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;&lt;/P&gt;
&lt;P&gt;The second program is its array-notation equivalent&lt;/P&gt;
&lt;P&gt;[cpp] int main(int argc, char ** argv) {&lt;BR /&gt; int array1[1000000];&lt;BR /&gt; int array2[1000000];&lt;BR /&gt; array1[0:1000000] = a;&lt;BR /&gt; array2[0:1000000] = a;&lt;BR /&gt; for (int j = 0; j &amp;lt; 1000; j++) {&lt;BR /&gt; array1[0:1000000] += array2[0:1000000];&lt;BR /&gt; }&lt;BR /&gt; cout &amp;lt;&amp;lt; array1[0]&amp;lt;&amp;lt; endl;&lt;BR /&gt; [/cpp]&lt;/P&gt;
&lt;P&gt;Without any optimization upon compilation, the first program (without the array-notation) took about 2.9 seconds and the second program took about 1.9 seconds. If i use optimization level -O3, the first program takes 0.6 seconds and the second program still takes 1.2 second. This is double the time the first program uses.&lt;/P&gt;
&lt;P&gt;Obviously, the two for-loops of the first program get vectorized, when using the -O3 option. Still, i would have thought, that the array-notation version was at least as fast. Did i miss something there? Maybe there is a bug somewhere when trying to optimize array-notation-code, so it generates less efficient code.If not - what do have to do to get the array-notation as fast as the "normal" code?&lt;/P&gt;
&lt;P&gt;I used a recent version of the cilkplus-branch of the gcc (a few days old) and a Core i7.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 13 Sep 2012 11:40:25 GMT</pubDate>
      <guid>https://community.intel.com/t5/Software-Archive/Array-notation-surprisingly-slow/m-p/991587#M27899</guid>
      <dc:creator>leifblaese</dc:creator>
      <dc:date>2012-09-13T11:40:25Z</dc:date>
    </item>
    <item>
      <title>I looked at the assembler</title>
      <link>https://community.intel.com/t5/Software-Archive/Array-notation-surprisingly-slow/m-p/991588#M27900</link>
      <description>When you exchange the line 
[cpp]

 array1[0:1000000] += array2[0:1000000];
[/cpp]
with a for-loop that does the exact same thing, you get a vectorized version. It then takes the same time as the version of the program not using array notation and it uses the %xmm-register when looking at the Assembler-Code. So the problem really is with creating SIMD-Code from array-notation inside a for-loop.</description>
      <pubDate>Thu, 13 Sep 2012 14:40:26 GMT</pubDate>
      <guid>https://community.intel.com/t5/Software-Archive/Array-notation-surprisingly-slow/m-p/991588#M27900</guid>
      <dc:creator>leifblaese</dc:creator>
      <dc:date>2012-09-13T14:40:26Z</dc:date>
    </item>
    <item>
      <title>I looked at the assembler</title>
      <link>https://community.intel.com/t5/Software-Archive/Array-notation-surprisingly-slow/m-p/991589#M27901</link>
      <description>I looked at the assembler-code (compiled it with flags -O3 and -S) and it seems that the second version of my program (array-notation version) is not being vectorized: When adding up the arrays, it does not use the %xmm-Register but the %edx-register. Oddly enough, when setting the values of the array = a (array1[0:100..] =a, array2 also) it does use the xmm0-register. So there seems to be a problem only with vectorizing array notation nested in a for-loop.

This is the first time i looked at assembler code so maybe someone else could try to replicate the problem and have a look too.</description>
      <pubDate>Thu, 13 Sep 2012 14:40:51 GMT</pubDate>
      <guid>https://community.intel.com/t5/Software-Archive/Array-notation-surprisingly-slow/m-p/991589#M27901</guid>
      <dc:creator>leifblaese</dc:creator>
      <dc:date>2012-09-13T14:40:51Z</dc:date>
    </item>
    <item>
      <title>It's hard to guess resulting</title>
      <link>https://community.intel.com/t5/Software-Archive/Array-notation-surprisingly-slow/m-p/991590#M27902</link>
      <description>It's hard to guess resulting code in a case like this where there is an opportunity for the compiler to short-cut your code and suppress loops.</description>
      <pubDate>Wed, 19 Sep 2012 19:47:56 GMT</pubDate>
      <guid>https://community.intel.com/t5/Software-Archive/Array-notation-surprisingly-slow/m-p/991590#M27902</guid>
      <dc:creator>TimP</dc:creator>
      <dc:date>2012-09-19T19:47:56Z</dc:date>
    </item>
    <item>
      <title>I have the same problem when</title>
      <link>https://community.intel.com/t5/Software-Archive/Array-notation-surprisingly-slow/m-p/991591#M27903</link>
      <description>I have the same problem when using array-notation with inline-if statements. Consider the edit-distance of two strings A,B. You can write that as

[cpp]
char A[100] = { ... }; // i didn't want to write the entire 100 symbols
char B[100] = { ... } ;
int s;
s[0:100] = (A[0:100] == B[0:100]) ? 1: 0;
cout &amp;lt;&amp;lt; s[0:100]
[/cpp]

Because of the output at the end, the compiler is forced to do the whole work, without shortcuts or anything. Still, when compiling with -O3 and looking at the assembler code, i get something like that:
EDIT: This is the part, where the two symbols are compared. Basically a for-loop that compares byte-for-byte two strings.

[cpp]
.L2:
 	movzbl	112(%rsp,%rax), %ecx
	cmpb	%cl, (%rsp,%rax)
	sete	%cl
	addl	$1, %edx
	movzbl	%cl, %ecx
	movl	%ecx, 224(%rsp,%rax,4)
	addq	$1, %rax
	cmpl	$99, %edx
	jle	.L2
	movl	224(%rsp), %esi
	movl	$_ZSt4cout, %edi
	call	_ZNSolsEi
	movl	228(%rsp), %esi
	movl	$_ZSt4cout, %edi
	call	_ZNSolsEi
	movl	232(%rsp), %esi
	movl	$_ZSt4cout, %edi
	call	_ZNSolsEi
	movl	236(%rsp), %esi
	movl	$_ZSt4cout, %edi
	call	_ZNSolsEi
	movl	240(%rsp), %esi
	movl	$_ZSt4cout, %edi
	call	_ZNSolsEi
	xorl	%eax, %eax
	addq	$632, %rsp
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
[/cpp]

The code itself is not that interesting, but note that there is not sign of %xmm registers or any commands that you would expect from SIMD-code (like movdqa or something like that). On the other hand, when you use a "normal" for-loop, you can generate SIMD-Code without a problem. Adding the '#pragma simd' leads to valid SIMD-Code as well, but i think it is because the compiler automatically detects that there is no dependence (because it works without the pragma as well).
I don't know whether this is only a problem with the gcc or also with an intel compiler, maybe someone could check that out.</description>
      <pubDate>Tue, 25 Sep 2012 10:14:02 GMT</pubDate>
      <guid>https://community.intel.com/t5/Software-Archive/Array-notation-surprisingly-slow/m-p/991591#M27903</guid>
      <dc:creator>leifblaese</dc:creator>
      <dc:date>2012-09-25T10:14:02Z</dc:date>
    </item>
  </channel>
</rss>

