伪共享测试

引用来自于 http://ifeve.com/falsesharing/

 

下面是我的实现

总结下,伪共享在cpu物理线程(超线程影响较少)越多的情况下对性能影响越大

而且在调用次数较少的情况下影响不大,因此不应该对伪共享引起的性能下降过多关注

如果你只有cpu核心少于4个就不要测试了.

 

测试时候注意jvm参数,cg会影响测试结果!同样cpu的睿频也会影响结果!

jvm是否把对象分配在一个缓存行中是无法保证的,所以我们只能理解连续分配的内存有很大的可能在一个缓存行中!

 

我的jvm参数

-server -verbose:gc -Xms1500m -Xmx2024m

 

 

package io.grass.core.collect;

import io.grass.util.StringUtils;
import io.grass.util.TimeSpan;



/**
 * jvm参数 !-server -verbose:gc -Xms1500m -Xmx2024m
 * 注意gc对垃圾回收的影响
 * @author zuoge85
 *
 */
public class FalseSharingTest {
	private static final int TEST_NUMS = 100000000;
	private static final int THREAD_NUMS = 4;

	public static void main(String[] args) throws InterruptedException {
		//测试伪装共享
		test1();
		System.out.println(StringUtils.center("sb", 90, '*'));
		test2();
	}
	static LongWarp[] longs = new LongWarp[THREAD_NUMS];
	static LongWarpPadded[] longPaddeds = new LongWarpPadded[THREAD_NUMS];
	static{
		for (int j = 0; j < THREAD_NUMS; j++) {
			longs[j] = new LongWarp();
		}
		for (int j = 0; j < THREAD_NUMS; j++) {
			longPaddeds[j] = new LongWarpPadded();
		}
	}
	public static void test1() throws InterruptedException{
		Thread[] ts=new Thread[THREAD_NUMS];
		
		for (int i = 0; i < ts.length; i++) {
			final int n = i;
			ts[i] = new Thread(){
				 public void run() {
					 TimeSpan ts = new TimeSpan();
					for (int j = 0; j < TEST_NUMS; j++) {
						 longs[n].setI(longs[n].getI()+1);
					}
					String end = ts.end();
					System.out.println("Thread"+n+":\t"+end+";end value:"+ longs[n]);
		         }
			};
		}
		for (int i = 0; i < ts.length; i++) {
			ts[i].start();
		}
		for (int i = 0; i < ts.length; i++) {
			ts[i].join();
		}
	}
	
	public static void test2() throws InterruptedException{
		Thread[] ts=new Thread[THREAD_NUMS];
		//final int[] ints = new int[THREAD_NUMS*1000];
		for (int i = 0; i < ts.length; i++) {
			final int n = i;
			ts[i] = new Thread(){
				 public void run() {
					TimeSpan ts = new TimeSpan();
					for (int j = 0; j < TEST_NUMS; j++) {
						longPaddeds[n].setI(longPaddeds[n].getI()+1);
					}
					String end = ts.end();
					System.out.println("Thread"+n+":\t"+end+";end value:"+ longPaddeds[n]);
		         }
			};
		}
		for (int i = 0; i < ts.length; i++) {
			ts[i].start();
		}
		for (int i = 0; i < ts.length; i++) {
			ts[i].join();
		}
	}
	public static class LongWarp{
		private volatile long i;

		public long getI() {
			return i;
		}

		public void setI(long i) {
			this.i = i;
		}

		@Override
		public String toString() {
			return "LongWarp [i=" + i + "]";
		}
	}
	 public static long sumPaddingToPreventOptimisation(final int index)
	 {
		 LongWarpPadded v = longPaddeds[index];
	      return v.p1 + v.p2 + v.p3 + v.p4 + v.p5 + v.p6;
	}

	public static class LongWarpPadded{
		private volatile long i;
		public  long p1, p2, p3, p4, p5, p6 = 7L;
		public long getI() {
			return i;
		}

		public void setI(long i) {
			this.i = i;
		}

		@Override
		public String toString() {
			return "LongWarpPadded [i=" + i + ", p1=" + p1 + ", p2=" + p2
					+ ", p3=" + p3 + ", p4=" + p4 + ", p5=" + p5 + ", p6=" + p6
					+ "]";
		}
		
	}
}





package io.grass.util;

import java.text.NumberFormat;

/**
 * 测试时间
 * 
 * @author zuoge85
 * 
 */
public class TimeSpan {
	public TimeSpan(){
		nf.setParseIntegerOnly(false);
		nf.setGroupingUsed(false);
		nf.setMaximumFractionDigits(6);
		nf.setMaximumFractionDigits(6);
		start();
		avgTime = System.nanoTime();
	}
	private long time;
	private long avgTime;
	public TimeSpan start() {
		time = System.nanoTime();
		return this;
	}
	private NumberFormat nf = NumberFormat.getNumberInstance();
	public String end() {
		return nf.format((System.nanoTime() - time) / 1000000000d);
	}
//	/**
//	 * 平均时间
//	 * @param i
//	 * @return
//	 */
//	public String avg(int i) {
//		return nf.format((System.nanoTime() - avgTime)/i / 1000000000d);
//	}
}

 

你可能感兴趣的:(java)