<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>fast memcpy</title>
		<link>http://www.allegro.cc/forums/view/551536</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Thu, 15 Dec 2005 01:45:05 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Hi, I have here a faster version of memcpy:</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="k1">typedef</span> <span class="k1">struct</span> <span class="k2">{</span> <span class="k1">unsigned</span> <span class="k1">char</span> dummy <span class="k2">[</span><span class="n">32</span><span class="k2">]</span><span class="k2">;</span> <span class="k2">}</span> DT<span class="k2">;</span></td></tr><tr><td class="number">2</td><td><span class="k1">void</span> fastcpy<span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span> dst, <span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span> src, size_t s<span class="k2">)</span> </td></tr><tr><td class="number">3</td><td><span class="k2">{</span></td></tr><tr><td class="number">4</td><td>         <span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span> sa <span class="k3">=</span> src<span class="k3">+</span>s<span class="k2">;</span></td></tr><tr><td class="number">5</td><td>         DT <span class="k3">*</span>d1 <span class="k3">=</span> <span class="k2">(</span>DT<span class="k3">*</span><span class="k2">)</span>dst <span class="k3">-</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">6</td><td>         DT <span class="k3">*</span>s1 <span class="k3">=</span> <span class="k2">(</span>DT<span class="k3">*</span><span class="k2">)</span>src <span class="k3">-</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">7</td><td>         size_t si <span class="k3">=</span> s <span class="k3">/</span> <span class="k1">sizeof</span><span class="k2">(</span>DT<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">8</td><td>&#160;</td></tr><tr><td class="number">9</td><td>         si <span class="k3">=</span> <span class="k2">(</span>si <span class="k3">+</span> <span class="n">7</span><span class="k2">)</span> <span class="k3">/</span> <span class="n">8</span><span class="k2">;</span></td></tr><tr><td class="number">10</td><td>         <span class="k1">switch</span><span class="k2">(</span>si % <span class="n">8</span><span class="k2">)</span> </td></tr><tr><td class="number">11</td><td>         <span class="k2">{</span></td></tr><tr><td class="number">12</td><td>                 <span class="k1">case</span> <span class="n">0</span><span class="k2">:</span> <span class="k1">do</span> <span class="k2">{</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">13</td><td>                 <span class="k1">case</span> <span class="n">7</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">14</td><td>                 <span class="k1">case</span> <span class="n">6</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">15</td><td>                 <span class="k1">case</span> <span class="n">5</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">16</td><td>                 <span class="k1">case</span> <span class="n">4</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">17</td><td>                 <span class="k1">case</span> <span class="n">3</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">18</td><td>                 <span class="k1">case</span> <span class="n">2</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">19</td><td>                 <span class="k1">case</span> <span class="n">1</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">20</td><td>                             <span class="k2">}</span> <span class="k1">while</span><span class="k2">(</span><span class="k3">-</span><span class="k3">-</span>si <span class="k3">&gt;</span> <span class="n">0</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">21</td><td>         <span class="k2">}</span></td></tr><tr><td class="number">22</td><td>&#160;</td></tr><tr><td class="number">23</td><td>         dst <span class="k3">=</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span><span class="k2">)</span>d1<span class="k2">;</span></td></tr><tr><td class="number">24</td><td>         src <span class="k3">=</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span><span class="k2">)</span>s1<span class="k2">;</span></td></tr><tr><td class="number">25</td><td>         <span class="k1">while</span><span class="k2">(</span>src <span class="k3">&lt;</span> sa<span class="k2">)</span> </td></tr><tr><td class="number">26</td><td>         <span class="k2">{</span></td></tr><tr><td class="number">27</td><td>                 <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>dst <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>src<span class="k2">;</span></td></tr><tr><td class="number">28</td><td>         <span class="k2">}</span></td></tr><tr><td class="number">29</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

What do you think about this code? Can you see any bugs or things I could change to do it faster?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (gering)</author>
		<pubDate>Sat, 10 Dec 2005 01:47:26 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Uhm, if you&#39;re going to post something like that, the least you could do is make a speed comparison chart.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (miran)</author>
		<pubDate>Sat, 10 Dec 2005 01:50:37 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>does it compile? EDIT: it does <img src="http://www.allegro.cc/forums/smileys/shocked.gif" alt=":o" /></p><p>I&#39;ve never seen a weird contruct like that with different parts of a loop in different case labels.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Tobi Vollebregt)</author>
		<pubDate>Sat, 10 Dec 2005 01:50:46 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Uhm, if you&#39;re going to post something like that, the least you could do is make a speed comparison chart.
</p></div></div><p>

I know, I have made a benchmark, but forgot to take it home from work. Results were like 15% - 30% faster on Linux, MacOSX and WindowsXP - compiled with gcc. Also testet with 32Bit and 64Bit(AMD) CPU. Have to try msvc, too. <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /></p><p>EDIT:<br />the MacOS version was the only one that was not slower than this one.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (gering)</author>
		<pubDate>Sat, 10 Dec 2005 02:00:06 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I&#39;ve never seen a weird contruct like that with different parts of a loop in different case labels.
</p></div></div><p>
Its called <a href="http://www.lysator.liu.se/c/duffs-device.html">duffs device</a>.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (kazzmir)</author>
		<pubDate>Sat, 10 Dec 2005 02:19:44 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>That is useful for masked blitting. As for your memcpy, try compiling with <i>-O2 -ffast-math -fomit-frame-pointer -funroll-loops</i> for maximun generic performance. I guess you can get it faster with assembler instructions, especially with MMX registers.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ReyBrujo)</author>
		<pubDate>Sat, 10 Dec 2005 02:24:39 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Copying around cache would probably give faster results. Only problem that needs SSE2 IIRC. Memory  aligning and other tricks can get memcpy speed up to somewhere around 80% of FSB theoretical maximum throughput.</p><p>[edit]</p><p>Also try copying between 32/64bit ints instead of chars. Speed should go up considerably. Using SIMD instinsic variables (128bit) would probably be even faster
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (HoHo)</author>
		<pubDate>Sat, 10 Dec 2005 02:29:01 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p><a href="http://www.allegro.cc/forums/thread/431305#target">Here</a> is my old blit code. The MMX version is very fast, but assumes a lot (aligning, size, pointers, etc).
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ReyBrujo)</author>
		<pubDate>Sat, 10 Dec 2005 02:35:04 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Fascinating. I wouldn&#39;t expect it to be faster than libc&#39;s memcpy.</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="p">#include &lt;string.h&gt;</span></td></tr><tr><td class="number">2</td><td><span class="p">#include &lt;stdio.h&gt;</span></td></tr><tr><td class="number">3</td><td><span class="p">#include &lt;time.h&gt;</span></td></tr><tr><td class="number">4</td><td><span class="p">#include &lt;sys/time.h&gt;</span></td></tr><tr><td class="number">5</td><td><span class="p">#include &lt;sys/resource.h&gt;</span></td></tr><tr><td class="number">6</td><td><span class="p">#include &lt;sys/types.h&gt;</span></td></tr><tr><td class="number">7</td><td>&#160;</td></tr><tr><td class="number">8</td><td><span class="p">#define CPUTIME (getrusage(RUSAGE_SELF,&amp;ruse),\</span></td></tr><tr><td class="number">9</td><td><span class="p">  ruse.ru_utime.tv_sec + ruse.ru_stime.tv_sec + \ </span></td></tr><tr><td class="number">10</td><td><span class="p">  1e-6 * (ruse.ru_utime.tv_usec + ruse.ru_stime.tv_usec)) </span></td></tr><tr><td class="number">11</td><td>&#160;</td></tr><tr><td class="number">12</td><td><span class="k1">struct</span> rusage ruse<span class="k2">;</span></td></tr><tr><td class="number">13</td><td>&#160;</td></tr><tr><td class="number">14</td><td><span class="k1">extern</span> <span class="k1">int</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_416.html" target="_blank">getrusage</a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">15</td><td>&#160;</td></tr><tr><td class="number">16</td><td><span class="k1">typedef</span> <span class="k1">struct</span> <span class="k2">{</span> <span class="k1">unsigned</span> <span class="k1">char</span> dummy <span class="k2">[</span><span class="n">32</span><span class="k2">]</span><span class="k2">;</span> <span class="k2">}</span> DT<span class="k2">;</span></td></tr><tr><td class="number">17</td><td><span class="k1">void</span> fastcpy<span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span> dst, <span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span> src, size_t s<span class="k2">)</span> </td></tr><tr><td class="number">18</td><td><span class="k2">{</span></td></tr><tr><td class="number">19</td><td>         <span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span> sa <span class="k3">=</span> src<span class="k3">+</span>s<span class="k2">;</span></td></tr><tr><td class="number">20</td><td>         DT <span class="k3">*</span>d1 <span class="k3">=</span> <span class="k2">(</span>DT<span class="k3">*</span><span class="k2">)</span>dst <span class="k3">-</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">21</td><td>         DT <span class="k3">*</span>s1 <span class="k3">=</span> <span class="k2">(</span>DT<span class="k3">*</span><span class="k2">)</span>src <span class="k3">-</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">22</td><td>         size_t si <span class="k3">=</span> s <span class="k3">/</span> <span class="k1">sizeof</span><span class="k2">(</span>DT<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">23</td><td>&#160;</td></tr><tr><td class="number">24</td><td>         si <span class="k3">=</span> <span class="k2">(</span>si <span class="k3">+</span> <span class="n">7</span><span class="k2">)</span> <span class="k3">/</span> <span class="n">8</span><span class="k2">;</span></td></tr><tr><td class="number">25</td><td>         <span class="k1">switch</span><span class="k2">(</span>si % <span class="n">8</span><span class="k2">)</span> </td></tr><tr><td class="number">26</td><td>         <span class="k2">{</span></td></tr><tr><td class="number">27</td><td>                 <span class="k1">case</span> <span class="n">0</span><span class="k2">:</span> <span class="k1">do</span> <span class="k2">{</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">28</td><td>                 <span class="k1">case</span> <span class="n">7</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">29</td><td>                 <span class="k1">case</span> <span class="n">6</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">30</td><td>                 <span class="k1">case</span> <span class="n">5</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">31</td><td>                 <span class="k1">case</span> <span class="n">4</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">32</td><td>                 <span class="k1">case</span> <span class="n">3</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">33</td><td>                 <span class="k1">case</span> <span class="n">2</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">34</td><td>                 <span class="k1">case</span> <span class="n">1</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">35</td><td>                             <span class="k2">}</span> <span class="k1">while</span><span class="k2">(</span><span class="k3">-</span><span class="k3">-</span>si <span class="k3">&gt;</span> <span class="n">0</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">36</td><td>         <span class="k2">}</span></td></tr><tr><td class="number">37</td><td>&#160;</td></tr><tr><td class="number">38</td><td>         dst <span class="k3">=</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span><span class="k2">)</span>d1<span class="k2">;</span></td></tr><tr><td class="number">39</td><td>         src <span class="k3">=</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span><span class="k2">)</span>s1<span class="k2">;</span></td></tr><tr><td class="number">40</td><td>         <span class="k1">while</span><span class="k2">(</span>src <span class="k3">&lt;</span> sa<span class="k2">)</span> </td></tr><tr><td class="number">41</td><td>         <span class="k2">{</span></td></tr><tr><td class="number">42</td><td>                 <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>dst <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>src<span class="k2">;</span></td></tr><tr><td class="number">43</td><td>         <span class="k2">}</span></td></tr><tr><td class="number">44</td><td><span class="k2">}</span></td></tr><tr><td class="number">45</td><td>&#160;</td></tr><tr><td class="number">46</td><td><span class="k1">int</span> main<span class="k2">(</span><span class="k1">void</span><span class="k2">)</span></td></tr><tr><td class="number">47</td><td><span class="k2">{</span></td></tr><tr><td class="number">48</td><td>   <span class="k1">char</span> <span class="k3">*</span>s1, <span class="k3">*</span>s2, <span class="k3">*</span>s3<span class="k2">;</span></td></tr><tr><td class="number">49</td><td>   <span class="k1">unsigned</span> <span class="k1">int</span> size<span class="k2">;</span></td></tr><tr><td class="number">50</td><td>   <span class="k1">double</span> t0, t1<span class="k2">;</span></td></tr><tr><td class="number">51</td><td>   </td></tr><tr><td class="number">52</td><td>   size <span class="k3">=</span> <span class="n">256</span><span class="k3">*</span><span class="n">1024</span><span class="k3">*</span><span class="n">1024</span><span class="k2">;</span></td></tr><tr><td class="number">53</td><td>   s1 <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_551.html" target="_blank">malloc</a><span class="k2">(</span>size<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">54</td><td>   s2 <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_551.html" target="_blank">malloc</a><span class="k2">(</span>size<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">55</td><td>   s3 <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_551.html" target="_blank">malloc</a><span class="k2">(</span>size<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">56</td><td>&#160;</td></tr><tr><td class="number">57</td><td>   s1<span class="k2">[</span>size-1<span class="k2">]</span> <span class="k3">=</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">58</td><td>   s2<span class="k2">[</span>size-1<span class="k2">]</span> <span class="k3">=</span> <span class="n">2</span><span class="k2">;</span></td></tr><tr><td class="number">59</td><td>   s3<span class="k2">[</span>size-1<span class="k2">]</span> <span class="k3">=</span> <span class="n">3</span><span class="k2">;</span></td></tr><tr><td class="number">60</td><td>  </td></tr><tr><td class="number">61</td><td>   t0 <span class="k3">=</span> CPUTIME<span class="k2">;</span></td></tr><tr><td class="number">62</td><td>   <a href="http://www.delorie.com/djgpp/doc/libc/libc_566.html" target="_blank">memcpy</a><span class="k2">(</span>s1, s2, size<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">63</td><td>   t1 <span class="k3">=</span> CPUTIME<span class="k2">;</span></td></tr><tr><td class="number">64</td><td>   <a href="http://www.delorie.com/djgpp/doc/libc/libc_624.html" target="_blank">printf</a><span class="k2">(</span><span class="s">"CPU time = %f secs.\n"</span>,t1-t0<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">65</td><td>   t0 <span class="k3">=</span> CPUTIME<span class="k2">;</span></td></tr><tr><td class="number">66</td><td>   fastcpy<span class="k2">(</span>s1, s3, size<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">67</td><td>   t1 <span class="k3">=</span> CPUTIME<span class="k2">;</span></td></tr><tr><td class="number">68</td><td>   <a href="http://www.delorie.com/djgpp/doc/libc/libc_624.html" target="_blank">printf</a><span class="k2">(</span><span class="s">"CPU time = %f secs.\n"</span>,t1-t0<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">69</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

Result:
</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
CPU time = 0.444931 secs.<br />CPU time = 0.278958 secs.
</p></div></div><p>
That&#39;s a factor of two (more or less). Maybe my test is flawed somehow? Or are computers really fast enough to copy around 512MB or RAM in a fraction of a second?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Evert)</author>
		<pubDate>Sat, 10 Dec 2005 02:42:48 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Evert, I dont see such improvements.</p><div class="source-code snippet"><div class="inner"><pre>~<span class="k3">/</span>tmp $ <span class="k3">!</span>gcc
gcc s.c <span class="k3">-</span>o s <span class="k3">-</span>O3 <span class="k3">-</span>ffast-math <span class="k3">-</span>funroll-loops
s.c:11:49: warning: backslash <span class="k1">and</span> newline separated by space
~<span class="k3">/</span>tmp $ .<span class="k3">/</span>s
CPU <a href="http://www.delorie.com/djgpp/doc/libc/libc_821.html" target="_blank">time</a> <span class="k3">=</span> <span class="n">1</span>.<span class="n">739736</span> secs.
CPU <a href="http://www.delorie.com/djgpp/doc/libc/libc_821.html" target="_blank">time</a> <span class="k3">=</span> <span class="n">1</span>.<span class="n">604756</span> secs.
~<span class="k3">/</span>tmp $ .<span class="k3">/</span>s
CPU <a href="http://www.delorie.com/djgpp/doc/libc/libc_821.html" target="_blank">time</a> <span class="k3">=</span> <span class="n">1</span>.<span class="n">719738</span> secs.
CPU <a href="http://www.delorie.com/djgpp/doc/libc/libc_821.html" target="_blank">time</a> <span class="k3">=</span> <span class="n">1</span>.<span class="n">560763</span> secs.
~<span class="k3">/</span>tmp $
</pre></div></div><p>

[edit]<br />In fact the following code shows memcpy is faster:
</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="p">#include &lt;string.h&gt;</span></td></tr><tr><td class="number">2</td><td><span class="p">#include &lt;stdio.h&gt;</span></td></tr><tr><td class="number">3</td><td><span class="p">#include &lt;time.h&gt;</span></td></tr><tr><td class="number">4</td><td><span class="p">#include &lt;sys/time.h&gt;</span></td></tr><tr><td class="number">5</td><td><span class="p">#include &lt;sys/resource.h&gt;</span></td></tr><tr><td class="number">6</td><td><span class="p">#include &lt;sys/types.h&gt;</span></td></tr><tr><td class="number">7</td><td>&#160;</td></tr><tr><td class="number">8</td><td><span class="p">#define MAX 32</span></td></tr><tr><td class="number">9</td><td><span class="p">#define TIMES 100</span></td></tr><tr><td class="number">10</td><td>&#160;</td></tr><tr><td class="number">11</td><td><span class="p">#define CPUTIME (getrusage(RUSAGE_SELF,&amp;ruse),\</span></td></tr><tr><td class="number">12</td><td><span class="p">  ruse.ru_utime.tv_sec + ruse.ru_stime.tv_sec + \  </span></td></tr><tr><td class="number">13</td><td>  <span class="n">1e</span><span class="k3">-</span><span class="n">6</span> <span class="k3">*</span> <span class="k2">(</span>ruse.ru_utime.tv_usec <span class="k3">+</span> ruse.ru_stime.tv_usec<span class="k2">)</span><span class="k2">)</span> </td></tr><tr><td class="number">14</td><td>&#160;</td></tr><tr><td class="number">15</td><td><span class="k1">struct</span> rusage ruse<span class="k2">;</span></td></tr><tr><td class="number">16</td><td>&#160;</td></tr><tr><td class="number">17</td><td><span class="k1">extern</span> <span class="k1">int</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_416.html" target="_blank">getrusage</a><span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">18</td><td>&#160;</td></tr><tr><td class="number">19</td><td><span class="k1">typedef</span> <span class="k1">struct</span> <span class="k2">{</span> <span class="k1">unsigned</span> <span class="k1">char</span> dummy <span class="k2">[</span><span class="n">32</span><span class="k2">]</span><span class="k2">;</span> <span class="k2">}</span> DT<span class="k2">;</span></td></tr><tr><td class="number">20</td><td><span class="k1">void</span> fastcpy<span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span> dst, <span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span> src, size_t s<span class="k2">)</span> </td></tr><tr><td class="number">21</td><td><span class="k2">{</span></td></tr><tr><td class="number">22</td><td>         <span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span> sa <span class="k3">=</span> src<span class="k3">+</span>s<span class="k2">;</span></td></tr><tr><td class="number">23</td><td>         DT <span class="k3">*</span>d1 <span class="k3">=</span> <span class="k2">(</span>DT<span class="k3">*</span><span class="k2">)</span>dst <span class="k3">-</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">24</td><td>         DT <span class="k3">*</span>s1 <span class="k3">=</span> <span class="k2">(</span>DT<span class="k3">*</span><span class="k2">)</span>src <span class="k3">-</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">25</td><td>         size_t si <span class="k3">=</span> s <span class="k3">/</span> <span class="k1">sizeof</span><span class="k2">(</span>DT<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">26</td><td>&#160;</td></tr><tr><td class="number">27</td><td>         si <span class="k3">=</span> <span class="k2">(</span>si <span class="k3">+</span> <span class="n">7</span><span class="k2">)</span> <span class="k3">/</span> <span class="n">8</span><span class="k2">;</span></td></tr><tr><td class="number">28</td><td>         <span class="k1">switch</span><span class="k2">(</span>si % <span class="n">8</span><span class="k2">)</span> </td></tr><tr><td class="number">29</td><td>         <span class="k2">{</span></td></tr><tr><td class="number">30</td><td>                 <span class="k1">case</span> <span class="n">0</span><span class="k2">:</span> <span class="k1">do</span> <span class="k2">{</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">31</td><td>                 <span class="k1">case</span> <span class="n">7</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">32</td><td>                 <span class="k1">case</span> <span class="n">6</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">33</td><td>                 <span class="k1">case</span> <span class="n">5</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">34</td><td>                 <span class="k1">case</span> <span class="n">4</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">35</td><td>                 <span class="k1">case</span> <span class="n">3</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">36</td><td>                 <span class="k1">case</span> <span class="n">2</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">37</td><td>                 <span class="k1">case</span> <span class="n">1</span><span class="k2">:</span>      <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>d1 <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>s1<span class="k2">;</span></td></tr><tr><td class="number">38</td><td>                             <span class="k2">}</span> <span class="k1">while</span><span class="k2">(</span><span class="k3">-</span><span class="k3">-</span>si <span class="k3">&gt;</span> <span class="n">0</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">39</td><td>         <span class="k2">}</span></td></tr><tr><td class="number">40</td><td>&#160;</td></tr><tr><td class="number">41</td><td>         dst <span class="k3">=</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span><span class="k2">)</span>d1<span class="k2">;</span></td></tr><tr><td class="number">42</td><td>         src <span class="k3">=</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span><span class="k2">)</span>s1<span class="k2">;</span></td></tr><tr><td class="number">43</td><td>         <span class="k1">while</span><span class="k2">(</span>src <span class="k3">&lt;</span> sa<span class="k2">)</span> </td></tr><tr><td class="number">44</td><td>         <span class="k2">{</span></td></tr><tr><td class="number">45</td><td>                 <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>dst <span class="k3">=</span> <span class="k3">*</span><span class="k3">+</span><span class="k3">+</span>src<span class="k2">;</span></td></tr><tr><td class="number">46</td><td>         <span class="k2">}</span></td></tr><tr><td class="number">47</td><td><span class="k2">}</span></td></tr><tr><td class="number">48</td><td>&#160;</td></tr><tr><td class="number">49</td><td><span class="k1">int</span> main<span class="k2">(</span><span class="k1">void</span><span class="k2">)</span></td></tr><tr><td class="number">50</td><td><span class="k2">{</span></td></tr><tr><td class="number">51</td><td>   <span class="k1">char</span> <span class="k3">*</span>s1, <span class="k3">*</span>s2, <span class="k3">*</span>s3<span class="k2">;</span></td></tr><tr><td class="number">52</td><td>   <span class="k1">unsigned</span> <span class="k1">int</span> size<span class="k2">;</span></td></tr><tr><td class="number">53</td><td>   <span class="k1">double</span> t0, t1<span class="k2">;</span></td></tr><tr><td class="number">54</td><td>   <span class="k1">unsigned</span> <span class="k1">int</span> i<span class="k2">;</span></td></tr><tr><td class="number">55</td><td>   </td></tr><tr><td class="number">56</td><td>   size <span class="k3">=</span> MAX<span class="k3">*</span><span class="n">1024</span><span class="k3">*</span><span class="n">1024</span><span class="k2">;</span></td></tr><tr><td class="number">57</td><td>   s1 <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_551.html" target="_blank">malloc</a><span class="k2">(</span>size<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">58</td><td>   s2 <span class="k3">=</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_551.html" target="_blank">malloc</a><span class="k2">(</span>size<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">59</td><td>   <span class="c">// s3 = malloc(size);</span></td></tr><tr><td class="number">60</td><td>&#160;</td></tr><tr><td class="number">61</td><td>   s1<span class="k2">[</span>size-1<span class="k2">]</span> <span class="k3">=</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">62</td><td>   s2<span class="k2">[</span>size-1<span class="k2">]</span> <span class="k3">=</span> <span class="n">2</span><span class="k2">;</span></td></tr><tr><td class="number">63</td><td>   <span class="c">// s3[size-1] = 3;</span></td></tr><tr><td class="number">64</td><td>&#160;</td></tr><tr><td class="number">65</td><td>   t0 <span class="k3">=</span> CPUTIME<span class="k2">;</span></td></tr><tr><td class="number">66</td><td>  <span class="k1">for</span> <span class="k2">(</span> i <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> i <span class="k3">&lt;</span> TIMES<span class="k2">;</span> i<span class="k3">+</span><span class="k3">+</span> <span class="k2">)</span><span class="k2">{</span></td></tr><tr><td class="number">67</td><td>     <a href="http://www.delorie.com/djgpp/doc/libc/libc_566.html" target="_blank">memcpy</a><span class="k2">(</span>s1, s2, size<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">68</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">69</td><td>   t1 <span class="k3">=</span> CPUTIME<span class="k2">;</span></td></tr><tr><td class="number">70</td><td>   <a href="http://www.delorie.com/djgpp/doc/libc/libc_624.html" target="_blank">printf</a><span class="k2">(</span><span class="s">"CPU time = %f secs.\n"</span>,t1-t0<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">71</td><td>   t0 <span class="k3">=</span> CPUTIME<span class="k2">;</span></td></tr><tr><td class="number">72</td><td>   <span class="k1">for</span> <span class="k2">(</span> i <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> i <span class="k3">&lt;</span> TIMES<span class="k2">;</span> i<span class="k3">+</span><span class="k3">+</span> <span class="k2">)</span><span class="k2">{</span></td></tr><tr><td class="number">73</td><td>     fastcpy<span class="k2">(</span>s1, s2, size<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">74</td><td>   <span class="k2">}</span></td></tr><tr><td class="number">75</td><td>   t1 <span class="k3">=</span> CPUTIME<span class="k2">;</span></td></tr><tr><td class="number">76</td><td>   <a href="http://www.delorie.com/djgpp/doc/libc/libc_624.html" target="_blank">printf</a><span class="k2">(</span><span class="s">"CPU time = %f secs.\n"</span>,t1-t0<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">77</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

</p><div class="source-code snippet"><div class="inner"><pre>~<span class="k3">/</span>tmp $ <span class="k3">!</span>gcc
gcc s.c <span class="k3">-</span>o s <span class="k3">-</span>O3 <span class="k3">-</span>ffast-math <span class="k3">-</span>funroll-loops
s.c:12:49: warning: backslash <span class="k1">and</span> newline separated by space
~<span class="k3">/</span>tmp $ .<span class="k3">/</span>s
CPU <a href="http://www.delorie.com/djgpp/doc/libc/libc_821.html" target="_blank">time</a> <span class="k3">=</span> <span class="n">18</span>.<span class="n">241228</span> secs.
CPU <a href="http://www.delorie.com/djgpp/doc/libc/libc_821.html" target="_blank">time</a> <span class="k3">=</span> <span class="n">19</span>.<span class="n">291067</span> secs.
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (kazzmir)</author>
		<pubDate>Sat, 10 Dec 2005 02:58:27 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><pre>reybrujo@ansalon:~$ ./test
CPU time = 0.646902 secs.
CPU time = 0.415936 secs.
</pre><p>

With -O3 there is a slight optimization, going down to 0.39xxxx.</p><p>For kazzmir test, I get</p><pre>reybrujo@ansalon:~$ ./test2
CPU time = 4.733280 secs.
CPU time = 4.358337 secs.</pre><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ReyBrujo)</author>
		<pubDate>Sat, 10 Dec 2005 03:08:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Or are computers really fast enough to copy around 512MB or RAM in a fraction of a second?
</p></div></div><p>If FSB is able to theoretically pass through ~6.4GiB of data I see no problem with copying 0.5G in a fraction of a second. Allthough I think 0.2s is a bit slow. But that&#39;s expectable from non optimized code <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /></p><p>[edit]<br />Using code from <a href="http://www.vik.cc/daniel/portfolio/memcpy.htm">here</a> and combining it with Evert&#39;s test I got this result:<br />CPU time = 0.532032 secs. // memcpy<br />CPU time = 0.232016 secs. // fastcpy<br />CPU time = 0.168011 secs. // code from url</p><p>[edit2]<br />A little more statistics <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /><br />CPU time = 0.496030 secs, 516.097817 MiB/s.<br />CPU time = 0.272017 secs, 941.117651 MiB/s.<br />CPU time = 0.188012 secs, 1361.615216 MiB/s.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (HoHo)</author>
		<pubDate>Sat, 10 Dec 2005 03:18:06 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>This seems to be slightly faster than the parents &#39;fastcopy&#39;, although admittedly less portable to 64-bit machines. It is very readable though.</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="p">#define copy1 \</span></td></tr><tr><td class="number">2</td><td><span class="p">  *dest = *source;\ </span></td></tr><tr><td class="number">3</td><td><span class="p">  dest++;\ </span></td></tr><tr><td class="number">4</td><td><span class="p">  source++; </span></td></tr><tr><td class="number">5</td><td>&#160;</td></tr><tr><td class="number">6</td><td><span class="p">#define copy2 \</span></td></tr><tr><td class="number">7</td><td><span class="p">  *(unsigned short *)dest = *(unsigned short *)source;\ </span></td></tr><tr><td class="number">8</td><td><span class="p">  dest += 2;\ </span></td></tr><tr><td class="number">9</td><td><span class="p">  source += 2; </span></td></tr><tr><td class="number">10</td><td>&#160;</td></tr><tr><td class="number">11</td><td><span class="p">#define copy4 \</span></td></tr><tr><td class="number">12</td><td><span class="p">  *(unsigned int *)dest = *(unsigned int *)source;\ </span></td></tr><tr><td class="number">13</td><td><span class="p">  dest += 4;\ </span></td></tr><tr><td class="number">14</td><td><span class="p">  source += 4;\ </span></td></tr><tr><td class="number">15</td><td><span class="p"> </span></td></tr><tr><td class="number">16</td><td><span class="p">#define copy8 \</span></td></tr><tr><td class="number">17</td><td><span class="p">  *(unsigned long *)dest = *(unsigned long *)source;\ </span></td></tr><tr><td class="number">18</td><td><span class="p">  dest += 8;\ </span></td></tr><tr><td class="number">19</td><td><span class="p">  source += 8;\ </span></td></tr><tr><td class="number">20</td><td><span class="p">   </span></td></tr><tr><td class="number">21</td><td>&#160;</td></tr><tr><td class="number">22</td><td><span class="k1">void</span> mycopy<span class="k2">(</span> <span class="k1">unsigned</span> <span class="k1">char</span> <span class="k3">*</span> dest, <span class="k1">unsigned</span> <span class="k1">char</span> <span class="k3">*</span> source, size_t s <span class="k2">)</span><span class="k2">{</span></td></tr><tr><td class="number">23</td><td>  size_t bytes <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">24</td><td>  <span class="k1">while</span> <span class="k2">(</span> s <span class="k2">)</span><span class="k2">{</span></td></tr><tr><td class="number">25</td><td>    <span class="k1">switch</span><span class="k2">(</span> s <span class="k2">)</span><span class="k2">{</span></td></tr><tr><td class="number">26</td><td>      <span class="k1">case</span> <span class="n">1</span> <span class="k2">:</span> <span class="k2">{</span></td></tr><tr><td class="number">27</td><td>           copy1<span class="k2">;</span></td></tr><tr><td class="number">28</td><td>           s--<span class="k2">;</span></td></tr><tr><td class="number">29</td><td>           <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">30</td><td>         <span class="k2">}</span></td></tr><tr><td class="number">31</td><td>      <span class="k1">case</span> <span class="n">2</span> <span class="k2">:</span> <span class="k2">{</span></td></tr><tr><td class="number">32</td><td>           copy2<span class="k2">;</span></td></tr><tr><td class="number">33</td><td>           s <span class="k3">-</span><span class="k3">=</span> <span class="n">2</span><span class="k2">;</span></td></tr><tr><td class="number">34</td><td>           <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">35</td><td>         <span class="k2">}</span></td></tr><tr><td class="number">36</td><td>      <span class="k1">case</span> <span class="n">3</span> <span class="k2">:</span> <span class="k2">{</span></td></tr><tr><td class="number">37</td><td>           copy2<span class="k2">;</span></td></tr><tr><td class="number">38</td><td>           copy1<span class="k2">;</span></td></tr><tr><td class="number">39</td><td>           s <span class="k3">-</span><span class="k3">=</span> <span class="n">3</span><span class="k2">;</span></td></tr><tr><td class="number">40</td><td>           <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">41</td><td>         <span class="k2">}</span></td></tr><tr><td class="number">42</td><td>      <span class="k1">case</span> <span class="n">4</span> <span class="k2">:</span> <span class="k2">{</span></td></tr><tr><td class="number">43</td><td>           copy4<span class="k2">;</span></td></tr><tr><td class="number">44</td><td>           s <span class="k3">-</span><span class="k3">=</span> <span class="n">4</span><span class="k2">;</span></td></tr><tr><td class="number">45</td><td>           <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">46</td><td>         <span class="k2">}</span></td></tr><tr><td class="number">47</td><td>      <span class="k1">case</span> <span class="n">5</span> <span class="k2">:</span> <span class="k2">{</span></td></tr><tr><td class="number">48</td><td>           copy4<span class="k2">;</span></td></tr><tr><td class="number">49</td><td>           copy1<span class="k2">;</span></td></tr><tr><td class="number">50</td><td>           s <span class="k3">-</span><span class="k3">=</span> <span class="n">5</span><span class="k2">;</span></td></tr><tr><td class="number">51</td><td>           <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">52</td><td>         <span class="k2">}</span></td></tr><tr><td class="number">53</td><td>      <span class="k1">case</span> <span class="n">6</span> <span class="k2">:</span> <span class="k2">{</span></td></tr><tr><td class="number">54</td><td>           copy4<span class="k2">;</span></td></tr><tr><td class="number">55</td><td>           copy2<span class="k2">;</span></td></tr><tr><td class="number">56</td><td>           s <span class="k3">-</span><span class="k3">=</span> <span class="n">6</span><span class="k2">;</span></td></tr><tr><td class="number">57</td><td>           <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">58</td><td>         <span class="k2">}</span></td></tr><tr><td class="number">59</td><td>      <span class="k1">case</span> <span class="n">7</span> <span class="k2">:</span> <span class="k2">{</span></td></tr><tr><td class="number">60</td><td>           copy4<span class="k2">;</span></td></tr><tr><td class="number">61</td><td>           copy2<span class="k2">;</span></td></tr><tr><td class="number">62</td><td>           copy1<span class="k2">;</span></td></tr><tr><td class="number">63</td><td>           s <span class="k3">-</span><span class="k3">=</span> <span class="n">7</span><span class="k2">;</span></td></tr><tr><td class="number">64</td><td>         <span class="k2">}</span></td></tr><tr><td class="number">65</td><td>      <span class="k1">default</span> <span class="k2">:</span> <span class="k2">{</span></td></tr><tr><td class="number">66</td><td>           copy8<span class="k2">;</span></td></tr><tr><td class="number">67</td><td>           s <span class="k3">-</span><span class="k3">=</span> <span class="n">8</span><span class="k2">;</span></td></tr><tr><td class="number">68</td><td>          <span class="k2">}</span></td></tr><tr><td class="number">69</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">70</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">71</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

When run with 32 megs + 3 bytes and 100 times each I get the following.
</p><div class="source-code snippet"><div class="inner"><pre><a href="http://www.delorie.com/djgpp/doc/libc/libc_566.html" target="_blank">memcpy</a> <span class="k3">-</span> CPU <a href="http://www.delorie.com/djgpp/doc/libc/libc_821.html" target="_blank">time</a> <span class="k3">=</span> <span class="n">9</span>.<span class="n">766516</span> secs.
fastcpy <span class="k3">-</span> CPU <a href="http://www.delorie.com/djgpp/doc/libc/libc_821.html" target="_blank">time</a> <span class="k3">=</span> <span class="n">9</span>.<span class="n">682528</span> secs.
mycop <span class="k3">-</span> CPU <a href="http://www.delorie.com/djgpp/doc/libc/libc_821.html" target="_blank">time</a> <span class="k3">=</span> <span class="n">9</span>.<span class="n">649533</span> secs.
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (kazzmir)</author>
		<pubDate>Sat, 10 Dec 2005 05:29:20 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I only tried Evert&#39;s test quickly, but I found that the results depended on the order in which the functions were called.  Whichever of fastcpy() or memcpy() was called second was faster.  If I then repeated the calls then the came out pretty much the same.  I haven&#39;t investigated, but I assume it&#39;s due to cache effects.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Peter Wang)</author>
		<pubDate>Sat, 10 Dec 2005 06:03:20 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I haven&#39;t investigated, but I assume it&#39;s due to cache effects.
</p></div></div><p>When moving 256M of data around, 0.5-2M of cache usually doesn&#39;t make much of a difference <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /></p><p>[edit]<br />Though, your test are correct:<br />CPU time = 0.500031 secs, 511.968258 MiB/s.  //memcpy<br />CPU time = 0.156010 secs, 1640.920454 MiB/s. //memcpy<br />CPU time = 0.216013 secs, 1185.113859 MiB/s. //fastcpy<br />CPU time = 0.156010 secs, 1640.920454 MiB/s. //fastcpy<br />CPU time = 0.160010 secs, 1599.900006 MiB/s. //thingie from net<br />CPU time = 0.156010 secs, 1640.920454 MiB/s. //thingie from net</p><p>It might be about chache but probably not data cache. Perhaps code gets cached and some jumps get predicted better in subsequent runs. Also walking through the arrays might help for some reason.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (HoHo)</author>
		<pubDate>Sat, 10 Dec 2005 06:09:52 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="source-code snippet"><div class="inner"><pre><span class="p">#define copy8 \</span>
<span class="p">  *(unsigned long *)dest = *(unsigned long *)source;\  </span>
  dest <span class="k3">+</span><span class="k3">=</span> <span class="n">8</span><span class="k2">;</span>\ 
  source <span class="k3">+</span><span class="k3">=</span> <span class="n">8</span><span class="k2">;</span>\
</pre></div></div><p>That doesnt actually coppy 8 bytes you know. At least not on ia32. You need <b>uint64_t</b> or <b>unsigned long long</b>.</p><p>edit: fixed typo.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Sat, 10 Dec 2005 06:23:48 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
You need uint32_t or unsigned long long.
</p></div></div><p>No, you would need either uint64_t or unsigned long long <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" /></p><p>Too bad I don&#39;t have the DDJ journal with me right now. They had a code in there that could acieve performandce of about 5.5GiB/s on nullifying 10MiB of memory and ~12GiB/s when nulling 128kiB.<br />Their test machine was 3GHz P4 with 800MHz FSB (theoretical maximum throughput 6.4GiB/s)
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (HoHo)</author>
		<pubDate>Sat, 10 Dec 2005 06:43:07 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
No, you would need either uint64_t or unsigned long long <img src="http://www.allegro.cc/forums/smileys/tongue.gif" alt=":P" />
</p></div></div><p>Ooops, typo <img src="http://www.allegro.cc/forums/smileys/shocked.gif" alt=":o" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Thomas Fjellstrom)</author>
		<pubDate>Sat, 10 Dec 2005 08:16:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I haven&#39;t tried it. But if this behaves the same as memcpy except faster, then you should send it to the gcc people.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Karadoc ~~)</author>
		<pubDate>Sat, 10 Dec 2005 09:41:18 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>has anyone written patches for blit using any of these techniques?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (A J)</author>
		<pubDate>Sat, 10 Dec 2005 11:37:40 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>@HoHo
</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
[edit]<br />Using code from here [vik.cc] and combining it with Evert&#39;s test I got this result:<br />CPU time = 0.532032 secs. // memcpy<br />CPU time = 0.232016 secs. // fastcpy<br />CPU time = 0.168011 secs. // code from url</p><p>[edit2]<br />A little more statistics <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /><br />CPU time = 0.496030 secs, 516.097817 MiB/s.<br />CPU time = 0.272017 secs, 941.117651 MiB/s.<br />CPU time = 0.188012 secs, 1361.615216 MiB/s.
</p></div></div><p>

I know this url, too. Had also tests with this version of memcpy... but it was always same speed as fastcopy on 32Bit machines. On 64Bit I got an segmentation fault with &quot;code from url&quot;. <img src="http://www.allegro.cc/forums/smileys/shocked.gif" alt=":o" /></p><p>@Karadoc
</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
I haven&#39;t tried it. But if this behaves the same as memcpy except faster, then you should send it to the gcc people.
</p></div></div><p>
<img src="http://www.allegro.cc/forums/smileys/cool.gif" alt="8-)" /><br />does someone have the gcc implementation?</p><p>@A J
</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
has anyone written patches for blit using any of these techniques?
</p></div></div><p>
I have written a &lt;vector&gt;, &lt;list&gt; and &lt;string&gt;... getting a lot faster than stl.</p><p>here the memmove:
</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="k1">void</span><span class="k3">*</span> fastmove<span class="k2">(</span><span class="k1">void</span><span class="k3">*</span> dst, <span class="k1">void</span><span class="k3">*</span> src, <span class="k1">unsigned</span> <span class="k1">long</span> count<span class="k2">)</span></td></tr><tr><td class="number">2</td><td><span class="k2">{</span></td></tr><tr><td class="number">3</td><td>  <span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span> dst8 <span class="k3">=</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span><span class="k2">)</span>dst<span class="k2">;</span></td></tr><tr><td class="number">4</td><td>  <span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span> src8 <span class="k3">=</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span><span class="k2">)</span>src<span class="k2">;</span></td></tr><tr><td class="number">5</td><td>&#160;</td></tr><tr><td class="number">6</td><td>  <span class="k1">if</span> <span class="k2">(</span>dst8 <span class="k3">&lt;</span><span class="k3">=</span> src8 <span class="k3">|</span><span class="k3">|</span> src8 <span class="k3">+</span> count <span class="k3">&lt;</span> dst8<span class="k2">)</span></td></tr><tr><td class="number">7</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">8</td><td>    fastcopy<span class="k2">(</span>dst8, src8, count<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">9</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">10</td><td>  <span class="k1">else</span></td></tr><tr><td class="number">11</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">12</td><td>    <span class="k1">long</span> delta <span class="k3">=</span> <span class="k2">(</span>src8 <span class="k3">+</span> count<span class="k2">)</span> <span class="k3">-</span> dst8<span class="k2">;</span></td></tr><tr><td class="number">13</td><td>&#160;</td></tr><tr><td class="number">14</td><td>    fastcopy<span class="k2">(</span>dst8 <span class="k3">+</span> delta, src8 <span class="k3">+</span> delta, delta<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">15</td><td>    fastcopy<span class="k2">(</span>dst8, src8, count <span class="k3">-</span> delta<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">16</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">17</td><td>&#160;</td></tr><tr><td class="number">18</td><td>  <span class="k1">return</span> dst<span class="k2">;</span></td></tr><tr><td class="number">19</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

[edit]<br />Can someone test if the fastcopy copies the data correctly? <img src="http://www.allegro.cc/forums/smileys/undecided.gif" alt=":-/" /> plssss
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (gering)</author>
		<pubDate>Sat, 10 Dec 2005 20:50:39 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;ve tried using 64 bit mmx registers in asm to blit, it&#39;s about 8% faster (on my machine) than using a slightly unrolled loop using the 32 bit general registers.  The Pentium 3? or was it 4? can use SSE registers with 128 bits at a time.  You can&#39;t use fpu registers because some bit combinations will cause exceptions, slowing things down.  I don&#39;t have SSE stuff so I can&#39;t test that.  The AMD 64 bitters I have no idea about.</p><p>AMD K6-2 does a string (rep stosd) set about as fast as an unrolled loop with 32 bit regs, Intel is faster with the 32 bit regs.  Copying is always faster than the string instructions with regs on all my computers.</p><p>So I always use MMX when I&#39;m trying for max FPS or whatever.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Arthur Kalliokoski)</author>
		<pubDate>Sun, 11 Dec 2005 06:18:25 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>how about using the 64bit general purpose registers of the AMD64.. thats got to be quicker than the 64bit MMX registers?    or is the limit still the FSB?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (A J)</author>
		<pubDate>Sun, 11 Dec 2005 06:22:54 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="k1">void</span><span class="k3">*</span> zMem::Copy<span class="k2">(</span><span class="k1">void</span><span class="k3">*</span> dst, <span class="k1">const</span> <span class="k1">void</span><span class="k3">*</span> src, <span class="k1">unsigned</span> <span class="k1">long</span> cnt<span class="k2">)</span></td></tr><tr><td class="number">2</td><td><span class="k2">{</span></td></tr><tr><td class="number">3</td><td>  b32_t<span class="k3">*</span> dst32 <span class="k3">=</span> <span class="k2">(</span>b32_t<span class="k3">*</span><span class="k2">)</span>dst<span class="k2">;</span>    <span class="c">// 256 Bit</span></td></tr><tr><td class="number">4</td><td>  b32_t<span class="k3">*</span> src32 <span class="k3">=</span> <span class="k2">(</span>b32_t<span class="k3">*</span><span class="k2">)</span>src<span class="k2">;</span></td></tr><tr><td class="number">5</td><td>&#160;</td></tr><tr><td class="number">6</td><td>  <span class="k1">unsigned</span> <span class="k1">long</span>  cnt32 <span class="k3">=</span> cnt <span class="k3">/</span> <span class="k1">sizeof</span><span class="k2">(</span>b32_t<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">7</td><td>  <span class="k1">unsigned</span> <span class="k1">long</span>  rst32 <span class="k3">=</span> cnt % <span class="k1">sizeof</span><span class="k2">(</span>b32_t<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">8</td><td>  </td></tr><tr><td class="number">9</td><td>  <span class="k1">while</span> <span class="k2">(</span>cnt32-- <span class="k3">&gt;</span> <span class="n">0</span><span class="k2">)</span> <span class="k3">*</span>dst32<span class="k3">+</span><span class="k3">+</span> <span class="k3">=</span> <span class="k3">*</span>src32<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span></td></tr><tr><td class="number">10</td><td>&#160;</td></tr><tr><td class="number">11</td><td>  <span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span> dst1 <span class="k3">=</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span><span class="k2">)</span>dst32<span class="k2">;</span></td></tr><tr><td class="number">12</td><td>  <span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span> src1 <span class="k3">=</span> <span class="k2">(</span><span class="k1">unsigned</span> <span class="k1">char</span><span class="k3">*</span><span class="k2">)</span>src32<span class="k2">;</span></td></tr><tr><td class="number">13</td><td>&#160;</td></tr><tr><td class="number">14</td><td>  <span class="k1">while</span> <span class="k2">(</span>rst32-- <span class="k3">&gt;</span> <span class="n">0</span><span class="k2">)</span> <span class="k3">*</span>dst1<span class="k3">+</span><span class="k3">+</span> <span class="k3">=</span> <span class="k3">*</span>src1<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span></td></tr><tr><td class="number">15</td><td>&#160;</td></tr><tr><td class="number">16</td><td>  <span class="k1">return</span> dst<span class="k2">;</span></td></tr><tr><td class="number">17</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>
This has same speed ... and schould work correctly...<br />The main speed optimation to libc is the use of <br /><b>typedef struct { unsigned char byte[32]; } b32_t;</b><br />no Duff&#39;s Device is needed.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (gering)</author>
		<pubDate>Tue, 13 Dec 2005 00:55:16 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I have read in some of the P4/AMD64/ICC optimzation guides that array indexing is preferred over pointers, as this helps the compiler to avoid aliasing (or whatever its called), with pointers the compiler can not guarantee src and dst are not the same, or could overlap, therefore can not make many optimzations, however using array indexing, the compiler can figure out they dont overlap and can perform pipeline/SSE/SIMD/cache optimzations.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (A J)</author>
		<pubDate>Tue, 13 Dec 2005 11:05:23 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The aliasing issue is supposed to be that if you wind up with two pointers pointing to the same thing, one pointer could alter the &quot;true&quot; variable, and if this variable was also in a register somewhere else, the register would have the wrong value, like volitile variable.  There&#39;s supposed to be a switch to turn off the aliasing (i.e. you tell the compiler you&#39;re smart enough not to do that), but from what I&#39;ve seen it doesn&#39;t always work.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Arthur Kalliokoski)</author>
		<pubDate>Thu, 15 Dec 2005 01:45:05 +0000</pubDate>
	</item>
</rss>
