All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mentaqueue.test.throughput.TestAtomicQueue Maven / Gradle / Ivy

The newest version!
package org.mentaqueue.test.throughput;

import org.mentaaffinity.Affinity;
import org.mentaqueue.AtomicQueue;
import org.mentaqueue.util.Builder;
import org.mentaqueue.wait.ParkWaitStrategy;
import org.mentaqueue.wait.WaitStrategy;

/**
 * java -server -Xms1g -Xmx4g -XX:NewSize=512m -XX:MaxNewSize=1024m -cp target/classes/:../MentaAffinity/target/mentaaffinity.jar:../MentaLog/target/mentalog.jar:../MentaAffinity/lib/jna-3.5.1.jar org.mentaqueue.test.throughput.TestAtomicQueue 100000000 100000000
 * 
 * Finshed throughput test! messagesSent=100000000 mps=177226334 avgTime=5
 * 
 * @author Sergio Oliveira Jr.
 */
public class TestAtomicQueue {
	
	private static final int QUEUE_SIZE = 1024 * 1024;
	
	private static long START_TIME;
	
	public static void main(String[] args) {
		
		final long messagesToWarmup = Long.parseLong(args[0]);
		final long messagesToTest = Long.parseLong(args[1]);
		
		final AtomicQueue queue = new AtomicQueue(QUEUE_SIZE, MutableLong.BUILDER);
		
		final WaitStrategy producerWaitStrategy = new ParkWaitStrategy(true);
		final WaitStrategy consumerWaitStrategy = new ParkWaitStrategy();
		
		Thread producer = new Thread(new Runnable() {
			
			private final void send() {
				MutableLong ml;
				while((ml = queue.nextToDispatch()) == null) {
					producerWaitStrategy.waitForOtherThread();
				}
				ml.set(0);
				queue.flush(true); // send lazily to maximize batching and throughput
				producerWaitStrategy.reset();
			}

			@Override
			public void run() {
				
				Affinity.bind();
				
				// first warmup...
				for(int i = 0; i < messagesToWarmup; i++) {
					send();
				}
				
				// now send:
				START_TIME = System.nanoTime();
				for(int i = 0; i < messagesToTest; i++) {
					send();
				}
				
				Affinity.unbind();
			}
		}, "Thread-Producer");
		
		Thread consumer = new Thread(new Runnable() {

			@Override
			public void run() {
				
				Affinity.bind();
				
				long count = 0;
				
				long total = messagesToTest + messagesToWarmup;
				
				while (count < total) {
					
					long avail;
					
					while((avail = queue.availableToPoll()) == 0) {
						consumerWaitStrategy.waitForOtherThread();
					}
					
					consumerWaitStrategy.reset();
					
					for(int i = 0; i < avail; i++) {
						MutableLong ml = queue.poll();
						long ts = ml.get();
					}
					count += avail;
					queue.donePolling(true); // lazy!
				}
				
				long totalTime = System.nanoTime() - START_TIME;
				
				Affinity.unbind();
				
				long avg = totalTime / messagesToTest;
				
				long mps = (messagesToTest * 1000000000L) / totalTime;
				
				System.out.println("Finshed throughput test! messagesSent=" + messagesToTest + " mps=" + mps + " avgTime=" + avg);
				
			}
		}, "Thread-Consumer");
		
		if (Affinity.isAvailable()) {
			Affinity.assignToProcessor(2, producer);
			Affinity.assignToProcessor(3, consumer);
		} else {
			System.err.println("Thread affinity not available!");
		}
		
		consumer.start();
		try { Thread.sleep(1); } catch(Exception e) { }
		producer.start();

	}
		
	private static class MutableLong {
		
		private long value = 0L;

		public MutableLong(long value) {
			this.value = value;
		}

		public final long get() {
			return value;
		}

		public final void set(long value) {
			this.value = value;
		}
		
		@Override
		public String toString() {
			return String.valueOf(value);
		}
		
		public final static Builder BUILDER = new Builder() {
			@Override
	        public MutableLong newInstance() {
		        return new MutableLong(-1);
	        }
		};
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy