package water.init; import water.util.ArrayUtils; import water.util.Log; import water.util.Timer; public class MemoryBandwidth { public static void main(String[] args) { int num_threads = Runtime.getRuntime().availableProcessors(); double membw = run(num_threads); Log.info("Memory bandwidth (" + num_threads + " cores) : " + membw + " GB/s."); } /** * Compute memory bandwidth in bytes / second */ public static double run(int num_threads) { final double membw[] = new double[num_threads]; Thread[] threads = new Thread[num_threads]; for (int t=0;t<num_threads;++t) { final int thread_num = t; threads[t] = new Thread() { public void run() { MemoryBandwidth l = new MemoryBandwidth(); membw[thread_num] = l.run_benchmark(); } }; } for (int t=0;t<num_threads;++t) { threads[t].start(); } for (int t=0;t<num_threads;++t) { try { threads[t].join(); } catch (InterruptedException e) { e.printStackTrace(); } } return ArrayUtils.sum(membw); } // memory bandwidth in bytes / second double run_benchmark() { // use the lesser of 40MB or 10% of Heap final long M = Math.min(10000000l, Runtime.getRuntime().maxMemory()/10); int[] vals = water.MemoryManager.malloc4((int)M); double total; int repeats = 20; Timer timer = new Timer(); //ms long sum = 0; // write repeats * M ints // read repeats * M ints for (int l=repeats-1; l>=0; --l) { for (int i=0; i<M; ++i) { vals[i] = i + l; } sum = 0; for (int i=0; i<M; ++i) { sum += vals[i]; } } total = (double)timer.time()/1000./repeats; //use the sum in a way that doesn't affect the result (don't want the compiler to optimize it away) double time = total + ((M*(M-1)/2) - sum); // == total return (double)2*M*4/time; //(read+write) * 4 bytes } }