Created
August 3, 2012 15:41
-
-
Save ludovicc/3248840 to your computer and use it in GitHub Desktop.
Performance test for different methods of sequential IO
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package game; | |
import static java.lang.Integer.MAX_VALUE; | |
import static java.lang.System.out; | |
import static java.nio.channels.FileChannel.MapMode.READ_ONLY; | |
import static java.nio.channels.FileChannel.MapMode.READ_WRITE; | |
import java.io.BufferedInputStream; | |
import java.io.BufferedOutputStream; | |
import java.io.File; | |
import java.io.FileInputStream; | |
import java.io.FileOutputStream; | |
import java.io.InputStream; | |
import java.io.OutputStream; | |
import java.io.RandomAccessFile; | |
import java.nio.ByteBuffer; | |
import java.nio.MappedByteBuffer; | |
import java.nio.channels.FileChannel; | |
/** | |
* {@link http://mechanical-sympathy.blogspot.fr/2012/08/memory-access-patterns-are-important.html} | |
* | |
* Run with the -Xmx4g JVM option. | |
*/ | |
public class TestMemoryAccessPatterns { | |
private static final int LONG_SIZE = 8; | |
private static final int PAGE_SIZE = 2 * 1024 * 1024; | |
private static final int ONE_GIG = 1024 * 1024 * 1024; | |
private static final long TWO_GIG = 2L * ONE_GIG; | |
private static final int ARRAY_SIZE = (int) (TWO_GIG / LONG_SIZE); | |
private static final int WORDS_PER_PAGE = PAGE_SIZE / LONG_SIZE; | |
private static final int ARRAY_MASK = ARRAY_SIZE - 1; | |
private static final int PAGE_MASK = WORDS_PER_PAGE - 1; | |
private static final int PRIME_INC = 514229; | |
private static final long LARGE_PRIME_INC = 70368760954879L; | |
private static final long[] memory = new long[ARRAY_SIZE]; | |
static { | |
for (int i = 0; i < ARRAY_SIZE; i++) { | |
memory[i] = 777; | |
} | |
} | |
public enum StrideType { | |
LINEAR_WALK { | |
@Override | |
public int next(final int pageOffset, final int wordOffset, | |
final int pos) { | |
return (pos + 1) & ARRAY_MASK; | |
} | |
}, | |
RANDOM_PAGE_WALK { | |
@Override | |
public int next(final int pageOffset, final int wordOffset, | |
final int pos) { | |
return pageOffset + ((pos + PRIME_INC) & PAGE_MASK); | |
} | |
}, | |
RANDOM_HEAP_WALK { | |
@Override | |
public int next(final int pageOffset, final int wordOffset, | |
final int pos) { | |
return (int) (pos + LARGE_PRIME_INC) & ARRAY_MASK; | |
} | |
}; | |
public abstract int next(int pageOffset, int wordOffset, int pos); | |
} | |
public static void main(final String[] args) { | |
if (args.length == 0) { | |
System.err.println("Usage: TestMemoryAccessPatterns <stride>"); | |
System.err | |
.println("where stride is one of linear | random_page | random_heap"); | |
} | |
final StrideType strideType; | |
if ("linear".equals(args[0])) { | |
strideType = StrideType.LINEAR_WALK; | |
} else if ("random_page".equals(args[0])) { | |
strideType = StrideType.RANDOM_PAGE_WALK; | |
} else if ("random_heap".equals(args[0])) { | |
strideType = StrideType.RANDOM_HEAP_WALK; | |
} else { | |
throw new IllegalArgumentException("Unknown StrideType"); | |
} | |
for (int i = 0; i < 5; i++) { | |
perfTest(i, strideType); | |
} | |
} | |
private static void perfTest(final int runNumber, | |
final StrideType strideType) { | |
final long start = System.nanoTime(); | |
int pos = -1; | |
long result = 0; | |
for (int pageOffset = 0; pageOffset < ARRAY_SIZE; pageOffset += WORDS_PER_PAGE) { | |
for (int wordOffset = pageOffset, limit = pageOffset | |
+ WORDS_PER_PAGE; wordOffset < limit; wordOffset++) { | |
pos = strideType.next(pageOffset, wordOffset, pos); | |
result += memory[pos]; | |
} | |
} | |
final long duration = System.nanoTime() - start; | |
final double nsOp = duration / (double) ARRAY_SIZE; | |
if (208574349312L != result) { | |
throw new IllegalStateException(); | |
} | |
System.out.format("%d - %.2fns %s\n", Integer.valueOf(runNumber), | |
Double.valueOf(nsOp), strideType); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment