org.jgroups.tests.ShmTest Maven / Gradle / Ivy
package org.jgroups.tests;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
/**
* Tests the speed of message sending/receiving via shared memory. Start the server first, then the client.
* The server and client use a simple (and stupid) alternating bit protocol to rendezvous; this could be enhanced into
* a ring buffer to increase performance.
* @author Bela Ban
* @since 3.4
*/
public class ShmTest {
protected static final int NUM=1000000;
protected static final int SIZE=1000;
protected static final int PRINT=NUM / 10;
protected static final int MAX_BUSY_SPIN=1000;
protected static void start(boolean server) throws Exception {
RandomAccessFile file=new RandomAccessFile("/tmp/shm", "rwd");
FileChannel channel=file.getChannel();
MappedByteBuffer shared_buffer=channel.map(FileChannel.MapMode.READ_WRITE,0,SIZE + 10);
file.close();
int count=0; // messages written (server) or read (client)
int busy_spin=0;
if(server) {
while(count < NUM) {
byte input=shared_buffer.get(0);
//System.out.println("input = " + input);
if(input == 0) {
// write
byte[] buf=new byte[SIZE];
shared_buffer.put(buf, 0, buf.length);
shared_buffer.rewind();
shared_buffer.put((byte)1).rewind();
count++;
if(count % PRINT == 0)
System.out.println("wrote " + count);
}
else {
busy_spin=0;
while((input=shared_buffer.get(0)) != 0) {
if(busy_spin++ < MAX_BUSY_SPIN)
;
else
Thread.yield();
}
}
}
}
else {
long start=System.nanoTime();
while(count < NUM) {
byte input=shared_buffer.get(0);
//System.out.println("input = " + input);
if(input == 1) {
// write
byte[] buf=new byte[SIZE];
shared_buffer.get(buf,0,buf.length);
shared_buffer.rewind();
shared_buffer.put((byte)0).rewind();
count++;
if(count % PRINT == 0)
System.out.println("read " + count);
}
else {
busy_spin=0;
while((input=shared_buffer.get(0)) != 1) {
if(busy_spin++ < MAX_BUSY_SPIN)
;
else
Thread.yield();
}
}
}
long time=System.nanoTime() - start;
long reads_sec=(long)(NUM / (time/1000.0/1000.0/1000.0));
double ns_per_msg=time/NUM;
double ms_per_msg=(time/1000000.0)/NUM;
double throughput=(NUM * SIZE / 1000000) / (time/1000000000.0);
System.out.println((time/1000000.0) + " ms, " + reads_sec + " reads/sec, " + ns_per_msg + " ns/msg, " +
ms_per_msg + " ms/msg, " + throughput + " MB/sec");
}
}
public static void main(String[] args) throws Exception {
start(args.length > 0);
}
}