Advertisement
Guest User

Untitled

a guest
Dec 6th, 2013
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package frans;
  2.  
  3. /**
  4.  * Class to test access time (latency) for cache and RAM.
  5.  * Sequential access and random access of values in a long[] array.
  6.  *
  7.  * @author Frans Lundberg
  8.  */
  9. public class MemoryAccess {
  10.     static final int SIZE_CACHE = 100000;           // 100003 is prime. Total: 0.8 MB.
  11.     static final long REPS1_CACHE = 10 * 1000;      // for seq
  12.     static final long REPS2_CACHE = 100 * 1000000;  // for random
  13.     static final int SIZE_RAM = 500 * SIZE_CACHE;   // 400 MB of data
  14.     static final long REPS1_RAM = 10;               // for seq
  15.     static final long REPS2_RAM = 10 * 1000000;     // for random
  16.    
  17.     /**
  18.      * Sequential memory accesses to a long[] array.
  19.      * 'size' must be SIZE_CACHE or SIZE_RAM.
  20.      */
  21.     Result seq(final int size) {
  22.         long[] data = new long[size];
  23.        
  24.         for (int i = 0; i < data.length; i++) {
  25.             data[i] = 1;
  26.         }
  27.        
  28.         long t0 = 0;
  29.         long sum = 0;
  30.         long count;
  31.        
  32.         t0 = System.nanoTime();
  33.        
  34.         if (size == SIZE_CACHE) {
  35.             count = SIZE_CACHE * REPS1_CACHE;
  36.             for (int k = 0; k < REPS1_CACHE; k++) {
  37.                 for (int i = 0; i < SIZE_CACHE; i++) {                
  38.                     sum += data[i];
  39.                 }
  40.             }
  41.         } else if (size == SIZE_RAM) {
  42.             count = SIZE_RAM * REPS1_RAM;
  43.             for (int k = 0; k < REPS1_RAM; k++) {
  44.                 for (int i = 0; i < SIZE_RAM; i++) {                
  45.                     sum += data[i];
  46.                 }
  47.             }
  48.         } else {
  49.             throw new Error("Bad size: " + size);
  50.         }
  51.        
  52.         double time = (System.nanoTime() - t0) * 1e-9;
  53.         return new Result(count, time, sum);
  54.     }
  55.    
  56.    
  57.     /**
  58.      * Random memory access to a long[] array.
  59.      * 'size' must be SIZE_CACHE or SIZE_RAM.
  60.      */
  61.     Result random(final int size) {
  62.         long[] data = new long[size];
  63.         long t0;
  64.         long sum = 0;
  65.         long index = 0;
  66.         long count;
  67.        
  68.         for (int i = 0; i < size; i++) {
  69.             data[i] = 1L;
  70.         }
  71.        
  72.         t0 = System.nanoTime();
  73.        
  74.         if (size == SIZE_CACHE) {
  75.             count = REPS2_CACHE;
  76.             for (int k = 0; k < REPS2_CACHE; k++) {            
  77.                 sum += data[(int)(index % SIZE_CACHE)];
  78.                 index += 836413;
  79.             }
  80.         } else if (size == SIZE_RAM) {
  81.             count = REPS2_RAM;
  82.             for (int k = 0; k < REPS2_RAM; k++) {
  83.                 sum += data[(int)(index % SIZE_RAM)];
  84.                 index += 836413;
  85.             }
  86.         } else {
  87.             throw new Error("Bad size: " + size);
  88.         }
  89.        
  90.         double time = (System.nanoTime() - t0) * 1e-9;
  91.         return new Result(count, time, sum);
  92.     }
  93.    
  94.     void runTest(String name, TestMethod test) {
  95.         int reps = 8;
  96.         double minTime = Double.MAX_VALUE;
  97.         Result winner = null;
  98.        
  99.         System.out.println("---- " + name + " ----");
  100.        
  101.         for (int i = 0; i < reps; i++) {
  102.             Result res = test.run();
  103.             if (res.time < minTime) {
  104.                 winner = res;
  105.             }
  106.         }
  107.        
  108.         System.out.println(winner.toString());
  109.     }
  110.    
  111.     /** To store the result. */
  112.     static class Result {
  113.         long count;
  114.         long sum;
  115.         double time;
  116.        
  117.         Result(long count, double time, long sum) {
  118.             this.count = count;
  119.             this.time = time;
  120.             this.sum = sum;
  121.         }
  122.        
  123.         public String toString() {
  124.             double nanos = (time * 1e9) / count;
  125.             return String.format("Access time %.2f ns, time: %.3f s (sum:%d).\n", nanos, time, sum);
  126.         }
  127.     }
  128.    
  129.     static interface TestMethod {
  130.         public Result run();
  131.     }
  132.    
  133.     void go() {
  134.         runTest("cacheSeq", new TestMethod() {
  135.             public Result run() {
  136.                 return seq(SIZE_CACHE);
  137.             }
  138.         });
  139.        
  140.         runTest("cacheRan", new TestMethod() {
  141.             public Result run() {
  142.                 return random(SIZE_CACHE);
  143.             }
  144.         });
  145.        
  146.         runTest("ramSeq", new TestMethod() {
  147.             public Result run() {
  148.                 return seq(SIZE_RAM);
  149.             }
  150.         });
  151.        
  152.         runTest("ramRan", new TestMethod() {
  153.             public Result run() {
  154.                 return random(SIZE_RAM);
  155.             }
  156.         });
  157.     }
  158.    
  159.     public static void main(String[] args) {
  160.         new MemoryAccess().go();
  161.     }
  162. }
  163.  
  164. /*
  165. 131106
  166. ======
  167.  
  168.     Test        Access time
  169.     cacheSeq     0.33 ns,  0.69 cycles
  170.     cacheRan     3.16 ns,  6.64 cycles
  171.     ramSeq       0.56 ns,  1.37 cycles
  172.     ramRan      20.07 ns, 42.16 cycles
  173.  
  174. On my computer "Cissi":
  175.     Ubuntu 12.04, CPU: Intel(R) Core(TM) i7-3687U CPU @ 2.10GHz, Cache: 4096 KiB.
  176.     Java version:
  177.         Oracle JVM 1.7.0_25.
  178.         Java HotSpot(TM) 64-Bit Server VM (build 23.25-b01, mixed mode)
  179.  
  180. sudo cat /proc/cpuinfo | grep "cache"   -->
  181.   cache size    : 4096 KB
  182. sudo cat /proc/cpuinfo | fgrep 'cpu MHz'
  183.   Max freq: cpu MHz : 2101.000  <--> 0.476 ns / cycle
  184. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement