2013-10-21 39 views
2

参考地点。 http://en.wikipedia.org/wiki/Locality_of_reference。 所以它像迭代一个小的int数组会更快,然后迭代linkedList。 由于阵列是连续的,并且所有阵列都可以放入cpu缓存中,并且缓存未命中会更少。易变阵列和参考地点

但我想要一个简单的int数组和易失性数组之间的比较。 AFAIK在易失性数组上迭代会导致每次都进行易失性读取,这可能会在某些系统中导致在每次读取时更新缓存。

int[] arr; // assume here i have declared and initialized it. 
int sum = 0; 
for(int i=0;i<arr.length;i++){ 
    sum = sum + arr[i]; 
} 

挥发性计数器部分

volatile int[] arr; // assume here i have declared and initialized it. 
int sum = 0; 
for(int i=0;i<arr.length;i++){ 
    sum = sum + arr[i]; // volatile read everytime 
} 

所以他们会是相同或编译器就可以把所有的挥发性读入一个单一的挥发性读取(编译优化)

+1

你试过比较生成的字节码吗?当询问(非JIT)编译器优化时,这通常是一个很好的起点。 –

+2

我对你想做什么感到困惑。 'int arr;'不初始化数组。此外,这个正确的代码:'volatile int [] arr = new int [len];'不会用volatile元素初始化一个数组。只有对数组的volatile参考。 http://jeremymanson.blogspot.com/2009/06/volatile-arrays-in-java.html – Radiodef

+0

嗨yahh我知道..我说假设他们初始化那里..不想写代码:)。其次,我知道它是一个volatile引用数组,因此每次你执行arr [i]时它都是一个volatile变量,因为它首先读取数组和相应的位置 – veritas

回答

3

如果需要挥发性访问一个数组,你可以使用AtomicIntegerArray。这包装了一个int数组,但提供了线程安全语义。

AtomicIntegerArray array = new AtomicIntegerArray(100); 
array.addAndGet(1); 
array.lazySet(10, 123); 
int n = array.get(5); // volatile get 
array.set(9, 333); // volatile set. 
0

只是略有改善,以科学家的代码:你实际上并不需要额外的挥发性布尔标志,你可以只用以下度日:

volatile int[] array = ...; 

void write(int index, int value){ 
    array[index]=value; 
    array = array; // explicit volatile write 
} 

int read(int index){ 
    return array[index]; // implicit volatile read 
} 

主要的变化是,你不因为访问数组的第i个元素涉及读取对数组的volatile参考(JIT /编译器实际上是否是另一回事,但它必须为您提供相同的保证)。所以这非常好,因为它完全是你编写的代码。 可悲的是,这不适用于写入数组,所以你必须做到这一点非常丑陋的自我分配。

这就是说,AtomicIntegerArray类与此一样高效(至少希望如此),并使整个事情变得明确。