Skip to content

Instantly share code, notes, and snippets.

@nitsanw
Last active December 10, 2015 04:18
Show Gist options
  • Save nitsanw/4380323 to your computer and use it in GitHub Desktop.
Save nitsanw/4380323 to your computer and use it in GitHub Desktop.
Unaligned Memory Access Cost Experiment
package alignment;
import java.nio.ByteBuffer;
import util.UnsafeAccess;
import static util.UnsafeDirectByteBuffer.*;
import com.google.caliper.Param;
import com.google.caliper.SimpleBenchmark;
public class UnalignedMemoryAccessCostBenchmark extends SimpleBenchmark {
@Param(value = "0")
int offset;
@Param(value = "1")
int sizeInPages;
// buffy is a page aligned buffer, and a vampire slayer
private ByteBuffer buffy;
@Override
protected void setUp() throws Exception {
buffy = allocateAlignedByteBuffer(sizeInPages*PAGE_SIZE, PAGE_SIZE);
}
public int timeOffsetLongAccess(final int reps) throws InterruptedException {
long remaining = 0;
long startingAddress = getAddress(buffy);
// skip first line if not straddling 2 cache lines
if (offset + 8 < CACHE_LINE_SIZE) {
startingAddress += CACHE_LINE_SIZE + offset;
} else {
startingAddress += offset;
}
final long limit = getAddress(buffy) + buffy.remaining();
for (long i = 0; i < reps; i++) {
remaining = writeAndRead(i, startingAddress, limit);
}
return (int) remaining;
}
private long writeAndRead(final long value, final long startingAddress,
final long limit) {
long address = startingAddress;
final int repeat = 2048/sizeInPages;
for (int i = 0; i < repeat; i++) {
for (address = startingAddress; address < limit; address += CACHE_LINE_SIZE) {
UnsafeAccess.unsafe.putLong(address, value);
}
for (address = startingAddress; address < limit; address += CACHE_LINE_SIZE) {
if (UnsafeAccess.unsafe.getLong(address) != value)
throw new RuntimeException();
}
}
return limit - address + CACHE_LINE_SIZE;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment