[lkml]   [1996]   [Apr]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    SubjectRe: Ideas for reducing memory copying and zeroing times (fwd)
       Date: 	Fri, 19 Apr 1996 04:16:53 +0200
    From: Michael Riepe <>

    I guess the fastest (and shortest) way to do that on an 80x86 is:

    xorl %eax,%eax
    leal 4096(page_start),%esp
    <repeat 1024 times>
    pushl %eax
    <end repeat>

    Of course you will have to turn interrupts off while doing this, and
    you have to save and restore %esp - but it's twice as fast as your
    move-and-increment procedure (assuming that push, mov and increment
    operations each take 1 clock cycle - that's what my i486 documentation
    says) and takes only 1024+ bytes of code space. Your code takes at
    least(?) 4 bytes of code per word cleared, assuming 32-bit protected

    The cycle count for something like this is rarely of interest (unless
    the number of machine cycles exceeds a main memory cycle, which is
    typically around 100 ns). Anything like copying or zeroing a large
    block of memory is completely dominated by the memory accesses, not by
    the machine instructions.

    The important consideration is usually the width of the memory bus.
    Almost all 486 and 386dx systems have a 32 bit main memory bus, so
    using a 32 bit wide instruction will be efficient. Whether it's some
    convoluted sequence as above or rep stosd probably doesn't matter too

    The Pentium's a different story. It has a 64 bit data bus, and most
    Pentium systems (except some laptops and a few bottom end desktop
    systems) use a 64 bit main memory bus. It also has a write back
    cache, but it doesn't allocate a cache line on write (if a particular
    address is not cached, it writes through). This offers a number of
    possible strategies:

    1) Use a conventional method (rep stosd or rep movsd). This only
    writes 32 bits at a time, and since the destination is normally not
    cached (if we're trying to zero out a really large chunk of memory) it
    won't be in cache, so we only use half of the memory bus on the write
    cycle. Bad, especially on block zero.

    2) Preload the cache (a chunk at a time). This makes writes more
    efficient, since the data's written from the cache 64 bits per cycle,
    but it requires an extra read. This speeds up memcpy by about 10%, at
    least on my system.

    3) Use 64 bit instructions. There are very few 64 bit instructions on
    the x86 (cmpxchg8b and the FPU instructions). The FPU instructions
    are usable for this purpose, since there are integer instructions and
    the FPU registers are wide enough to hold a 64 bit integer with no
    loss of precision (read: corruption). They're slow (2-6 cycles), but
    that's OK even on a 90 MHz Pentium since 6 cycles is still quicker
    than a main memory cycle. I've found that performance using this
    technique is almost exactly double on block clear (60 vs. 30 MB/sec)
    and sharply improved on memcpy (35 vs. 19 MB/sec). This is a 90 MHz
    Pentium on an Intel Plato motherboard. I have a patch (see for details) that uses this

    There are a few high end systems that have a 128 bit wide main memory
    bus. I suspect that it would be better to preload the cache on these
    systems than to use 64 bit stores, although the numbers suggest it
    would be a toss up. If this were the case, I would use conventional
    32-bit instructions with cache preloading rather than the FPU.

    Robert Krawitz <>

    Member of the League for Programming Freedom -- mail
    Tall Clubs International -- or 1-800-521-2512

     \ /
      Last update: 2005-03-22 13:37    [W:0.021 / U:15.176 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site