STREAM Logo (Image)Department of Computer Science
School of Engineering and Applied Science
University of Virginia, Charlottesville, Virginia

FAQ's

  • Background:
  • What is STREAM?
  • Why should I care?
  • Technical Information:
  • How do I run STREAM?
  • How does STREAM count Bytes and FLOPs?
  • Administration:
  • Who is responsible for STREAM?
  • How can I help?
  • Future directions for STREAM?

  • What is STREAM?

    The STREAM benchmark is a simple synthetic benchmark program that measures sustainable memory bandwidth (in MB/s) and the corresponding computation rate for simple vector kernels. 

    Why should I care?

    Computer cpus are getting faster much more quickly than computer memory systems. As this progresses, more and more programs will be limited in performance by the memory bandwidth of the system, rather than by the computational performance of the cpu.

    As an extreme example, several current high-end machines run simple arithmetic kernels for out-of-cache operands at 4-5% of their rated peak speeds --- that means that they are spending 95-96% of their time idle and waiting for cache misses to be satisfied.

    The STREAM benchmark is specifically designed to work with datasets much larger than the available cache on any given system, so that the results are (presumably) more indicative of the performance of very large, vector style applications.

    If you want more words, I have written a paper on STREAM: Sustainable Memory Bandwidth in Current High Performance Computers

    A somewhat broader look on the issue, see my paper: Memory Bandwidth and Machine Balance in Current High Performance Computers. A version of this paper was published in the newsletter of the IEEE Technical Committee on Computer Architecture (TCCA) in December 1995. 


    How Do I Run STREAM?

    STREAM is relatively easy to run, though there are bazillions of variations in operating systems and hardware, so it is hard to be comprehensive.

    There are a couple of systems with precompiled binaries:

  • PC's running DOS - zipped binary package
  • PC's running Windows95/98/NT - use this binary
  • PC's running Linux - use this binary
  • Power Mac systems - grab this set of binaries
  • If there is not a precompiled binary, then you have to compile the code.

    Uniprocessor Runs

    If you want to run STREAM on a single processor, then you are in luck -- it is an easy thing to do.  Grab the source code from the source code directory at the ftp site.  You will need the main stream code in either Fortran or C, and you will need a timer code.  For unix/linux systems, the timer code provide (second_wall.c) works fine.  Some systems provide higher resolution timers -- check with the documentation on your own unix/linux box to see what you have access to.....

    Multiprocessor Runs

    If you want to run STREAM on multiple processors, then the situation is not quite so easy.

    First, you need to adjust the problem size so that the data is not cacheable.

    Second, you need to make sure that you are using a wall-clock timer instead of a cpu-time timer.

    Third, you need to figure out how to run the code in parallel.

    On "industrial-strength" systems, you may have an automatically parallelizing compiler for Fortran or C.  It should have no trouble parallelizing the four kernels in STREAM.

    If you do not have an automatically parallelizing compiler, you may still have a compiler with OpenMP support.   It requires only 4 OpenMP directives to parallelize STREAM.  Just insert "!$OMP PARALLEL DO" before each of the four main DO loops in the Fortran code.  The C pragma's for OpenMP are similar, but I don't remember the syntax off the top of my head.

    If you do not have a compiler with OpenMP support, you may need to figure out how to get pthreads (or NT threads) working.  You are on your own here, unfortunately.

    If you have no threads support and you want to see how bandwidth scales in a multiprocessor system, you can try the following hack:

  • set up a "background" version of STREAM with a very high value of "ntimes" (Fortran) or "NTIMES" (C).
  • set up a "foreground" version of STREAM with a normal value for ntimes/NTIMES.
  • start up as many "background" copies as you want
  • start up one "foreground" copy
  • The STREAM bandwidth will be approximately equal to the value for the "foreground" job times the total number of foreground + background jobs.
  • Note that results using this hack are not "standard" STREAM benchmark numbers, and I will not publish them in the tables, but they will give you an idea of the throughput of the memory system under test.
     

    Adjust the Problem Size

    STREAM is intended to measure the bandwidth from main memory.  It can, of course, be used to measure cache bandwidth as well, but that is not what I have been publishing at the web site.  Maybe someday....
     
    The general rule for STREAM is that each array must be at least 4x the size of the sum of all the last-level caches used in the run, or 1 Million elements -- whichever is larger.


    So, for a uniprocessor machine with a 256kB L2 cache (like a new PentiumIII, for example), each array needs to be at least 128k elements.   This is smaller than the standard test size of 2,000,000 elements, which is appropriate for systems with 4 MB L2 caches.   There should be relatively little difference in the performance of different sizes once the size of each array becomes significantly larger than the cache size, but since there are some differences (typically associated with TLB reach), for comparability I require that results even for small cache machines use 1 million elements whenever possible.  This requires only 22 MB, so it should be workable on even a 32 MB machine.

    If this size requirement is a problem and you are interested in submitting results on a system that cannot meet this criterion, e-mail me and we can discuss the issues.

    For an automatically parallelized run on (for example) 16 cpus, each with 8 MB L2 caches, the problem size must be increased to at least N=64,000,000.   This will require a lot of memory!  (about 1.5 GB)


    Who is responsible for STREAM?

    STREAM was created and is maintained by John McCalpin, mccalpin@cs.virginia.edu.

    NOTICE and DISCLAIMER

    The STREAM benchmark was developed while McCalpin was on the faculty at the University of Delaware. After three years at SGI, I am now employed by IBM, where I work on performance analysis of computer systems under development. The STREAM benchmark remains an independent academic project, which will not be influenced or directed by commercial concerns. In order to maintain this independence, the STREAM benchmark is hosted here at U.Va. under the sponsorship of Professor Alan Batson and Professor William Wulf

    How can I help?

    Contributions are always welcome!!!!

    STREAM has become a useful and important benchmark because lots of results are available. Please help us keep up with this rapidly changing market. If you have access to a new machine that is not listed here, give STREAM a try!

    (See the FTP Archives for the source code and comma-delimited database files with the raw data in them.) 


    Future Directions for STREAM?

    Extensions of the STREAM benchmark for the future are currently being considered. The main issues that need to be addressed are: A "second-generation" STREAM benchmark (STREAM2) is being evaluated, with the source code and some results available at the STREAM2 page.   STREAM2 emphases measurements across all levels of the memory hierarchy, and tries to focus on the difference between read and write performance in memory systems.

    Counting Bytes and FLOPS

    It may be surprising, but there are at least three different ways to count Bytes for a benchmark like STREAM, and unfortunately all three are in common use!

    The three conventions for counting can be called:

  • bcopy
  • STREAM
  • hardware
  • "bcopy" counts how many bytes get moved from one place in memory to another.  So if it takes your computer 1 second to  read 1 million bytes at one location and write those 1 million bytes to a second location, the resulting "bcopy bandwidth" is said to be "1 MB per second".
  • "STREAM" counts how many bytes the user asked to be read plus how many bytes the user asked to be written.  For the simple "Copy" kernel, this is exactly twice the number obtained from the "bcopy" convention.   Why does STREAM do this?  Because 3 of the 4 kernels do arithmetic, so it makes sense to count both the data read into the CPU and the data written back from the CPU.   The "Copy" kernel does no arithmetic, but I chose to count bytes the same way as the other three.
  • "hardware" may move a different number of bytes than what the user specified.  In particular, most cached systems perform what is called a "write allocate" when a store operation misses the data cache.  The system loads the cache line containing the data before overwriting it.

  • Why does it do this?
    It does it so that there will be a single copy of the cache line in the system for which all the bytes are current and valid.   If you only wrote 1/2 the bytes in the cache line, for example, the result would have to be merged with the other 1/2 of the bytes from memory.  The best place to do this is in the cache, so the data is loaded there first and life is much simpler.
     

    The table below shows how many Bytes and FLOPs are counted in each iteration of the STREAM loops.
    The test consists of multiple repetitions of four the kernels, and the best results of (typically) 10 trials are chosen.

        ------------------------------------------------------------------
        name        kernel                  bytes/iter      FLOPS/iter
        ------------------------------------------------------------------
        COPY:       a(i) = b(i)                 16              0
        SCALE:      a(i) = q*b(i)               16              1
        SUM:        a(i) = b(i) + c(i)          24              1
        TRIAD:      a(i) = b(i) + q*c(i)        24              2
        ------------------------------------------------------------------
    So you need to be careful comparing "MB/s" from different sources.  STREAM always uses the same approach, and always counts only the bytes that the user program requested to be loaded or stored, so results are always directly comparable.