usermode/library/malloc-hoard-old/benchmarks/cache-scratch/cache-scratch.cpp

00001 
00002 //
00003 // Hoard: A Fast, Scalable, and Memory-Efficient Allocator
00004 //        for Shared-Memory Multiprocessors
00005 // Contact author: Emery Berger, http://www.cs.utexas.edu/users/emery
00006 //
00007 // Copyright (c) 1998-2000, The University of Texas at Austin.
00008 //
00009 // This library is free software; you can redistribute it and/or modify
00010 // it under the terms of the GNU Library General Public License as
00011 // published by the Free Software Foundation, http://www.fsf.org.
00012 //
00013 // This library is distributed in the hope that it will be useful, but
00014 // WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016 // Library General Public License for more details.
00017 //
00019 
00020 /*
00021   cache-scratch.cpp
00022   ------------------------------------------------------------------------
00023   cache-scratch is a benchmark that exercises a heap's cache-locality.
00024   An allocator that allows multiple threads to re-use the same small
00025   object (possibly all in one cache-line) will scale poorly, while
00026   an allocator like Hoard will exhibit near-linear scaling.
00027   ------------------------------------------------------------------------
00028   @(#) $Id: cache-scratch.cpp,v 1.12 2000/09/28 17:01:30 emery Exp $
00029   ------------------------------------------------------------------------
00030   Emery Berger                    | <http://www.cs.utexas.edu/users/emery>
00031   Department of Computer Sciences |             <http://www.cs.utexas.edu>
00032   University of Texas at Austin   |                <http://www.utexas.edu>
00033   ========================================================================
00034 */
00035 
00036 /* Try the following (on a P-processor machine):
00037 
00038    cache-scratch 1 1000 1 1000000
00039    cache-scratch P 1000 1 1000000
00040 
00041    cache-scratch-hoard 1 1000 1 1000000
00042    cache-scratch-hoard P 1000 1 1000000
00043 
00044    The ideal is a P-fold speedup.
00045 */
00046 
00047 
00048 #include "arch-specific.h"
00049 #include "timer.h"
00050 
00051 #include <iostream.h>
00052 #include <stdlib.h>
00053 
00054 // This class just holds arguments to each thread.
00055 class workerArg {
00056 public:
00057   workerArg (char * obj, int objSize, int repetitions, int iterations)
00058     : _object (obj),
00059       _objSize (objSize),
00060       _iterations (iterations),
00061       _repetitions (repetitions)
00062   {}
00063 
00064   char * _object;
00065   int _objSize;
00066   int _iterations;
00067   int _repetitions;
00068 };
00069 
00070 
00071 extern "C" void * worker (void * arg)
00072 {
00073   // free the object we were given.
00074   // Then, repeatedly do the following:
00075   //   malloc a given-sized object,
00076   //   repeatedly write on it,
00077   //   then free it.
00078   workerArg * w = (workerArg *) arg;
00079   delete w->_object;
00080   for (int i = 0; i < w->_iterations; i++) {
00081     // Allocate the object.
00082     char * obj = new char[w->_objSize];
00083     // Write into it a bunch of times.
00084     for (int j = 0; j < w->_repetitions; j++) {
00085       for (int k = 0; k < w->_objSize; k++) {
00086         obj[k] = (char) k;
00087         volatile char ch = obj[k];
00088         ch++;
00089       }
00090     }
00091     // Free the object.
00092     delete [] obj;
00093   }
00094   delete w;
00095   return NULL;
00096 }
00097 
00098 
00099 int main (int argc, char * argv[])
00100 {
00101   int nthreads;
00102   int iterations;
00103   int objSize;
00104   int repetitions;
00105 
00106   if (argc > 4) {
00107     nthreads = atoi(argv[1]);
00108     iterations = atoi(argv[2]);
00109     objSize = atoi(argv[3]);
00110     repetitions = atoi(argv[4]);
00111   } else {
00112     cerr << "Usage: " << argv[0] << " nthreads iterations objSize repetitions" << endl;
00113     exit(1);
00114   }
00115 
00116   hoardThreadType * threads = new hoardThreadType[nthreads];
00117   hoardSetConcurrency (hoardGetNumProcessors());
00118 
00119   int i;
00120 
00121   // Allocate nthreads objects and distribute them among the threads.
00122   char ** objs = new char * [nthreads];
00123   for (i = 0; i < nthreads; i++) {
00124     objs[i] = new char[objSize];
00125   }
00126 
00127   Timer t;
00128   t.start();
00129 
00130   for (i = 0; i < nthreads; i++) {
00131     workerArg * w = new workerArg (objs[i], objSize, repetitions / nthreads, iterations);
00132     hoardCreateThread (threads[i], worker, (void *) w);
00133   }
00134   for (i = 0; i < nthreads; i++) {
00135     hoardJoinThread (threads[i]);
00136   }
00137   t.stop();
00138 
00139   delete [] threads;
00140   delete [] objs;
00141 
00142   cout << "Time elapsed = " << (double) t << " seconds." << endl;
00143   return 0;
00144 }

Generated on Sat Apr 23 11:43:35 2011 for Mnemosyne by  doxygen 1.4.7