Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.Random;
- public class CpuCacheTest {
- static final int
- POOL_MIN_BYTES = 1<<3,
- POOL_MAX_BYTES = 1<<28,
- ACCESS_ORDER_LIST_LENGTH = 10 * 1000 * 1000,
- NUM_REPEATS = 10;
- int numBytes;
- byte[] bytes;//the pool of bytes out in main memory
- int[] accessOrder;//will always be accessed sequentially
- CpuCacheTest(int sizeInBytes, boolean randomAccess){
- Random random = new Random();
- //populate a byte pool of the specified size
- this.numBytes = sizeInBytes;
- this.bytes = new byte[numBytes];
- for(int i=0; i < numBytes; ++i){//fill the array with something
- bytes[i] = (byte)(random.nextInt(127));
- }
- //generate an array of either sequential or random indexes of the pool
- accessOrder = new int[ACCESS_ORDER_LIST_LENGTH];
- for(int i=0; i < ACCESS_ORDER_LIST_LENGTH; ++i){
- if(randomAccess){
- accessOrder[i] = random.nextInt(numBytes);
- }else{
- accessOrder[i] = i % numBytes;
- }
- }
- //minimize chances of interruption
- System.gc();
- // System.runFinalization();//doesn't seem to matter
- }
- void iterateBytes(){
- long startNs = System.nanoTime();
- byte val = -1;
- for(int repetition=0; repetition < NUM_REPEATS; ++repetition){
- for(int accessIdx=0; accessIdx < ACCESS_ORDER_LIST_LENGTH; ++accessIdx){
- //do something so the compiler doesn't optimize the array access away
- val += bytes[accessOrder[accessIdx]];
- }
- }
- long endNs = System.nanoTime();
- long durationNs = Math.max(1, endNs - startNs);
- // System.out.print(pad(""+durationNs,' ',12));
- System.out.print(pad(""+megabytesPerSecond(durationNs),' ',12));
- }
- /**************************** main **************************************/
- public static void main(String... args){
- System.out.println("bytes fetched per microsecond (megabytes per second)");
- System.out.println("pool size sorted random");
- int stepFactor = 2;
- for(int sizeInBytes=POOL_MIN_BYTES; sizeInBytes <= POOL_MAX_BYTES; sizeInBytes *= stepFactor){
- System.out.print(pad(getAbbreviatedBytes(sizeInBytes)+"", ' ', 9));
- //streaming bytes sequentially from memory
- new CpuCacheTest(sizeInBytes, false).iterateBytes();
- //grabbing bytes randomly from memory
- new CpuCacheTest(sizeInBytes, true).iterateBytes();
- System.out.println();
- }
- }
- /************************** helpers **********************************/
- long megabytesPerSecond(long durationNs){
- double numOps = (double)(ACCESS_ORDER_LIST_LENGTH * NUM_REPEATS);
- double opsPerNs = numOps / (double)durationNs;
- return (long)(1000 * opsPerNs);
- }
- static String getAbbreviatedBytes(long bytes){
- if(bytes < 1<<10){ return bytes + "B"; }
- if(bytes < 1<<20){ return (bytes>>10) + "K"; }
- if(bytes < 1<<30){ return (bytes>>20) + "M"; }
- return (bytes>>30) + "G";
- }
- static String pad(String input, char padding, int length){
- if(input.length() > length){
- throw new IllegalArgumentException("input \""+input+"\" longer than maxLength="+length);
- }
- int charsToGo = length - input.length();
- return repeat(padding, charsToGo) + input;
- }
- static String repeat(char chr, int number) {
- StringBuilder sb = new StringBuilder();
- for(int i=0; i < number; ++i){
- sb.append(chr);
- }
- return sb.toString();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement