我正在研究Java 8中引入的并行排序的概念。
按照doc。
但是,规范未指定此最低限制。
当我在java.util.Arrays
中查找代码时,它被定义为
private static final int MIN_ARRAY_SORT_GRAN = 1 << 13;
即数组中的 8192 值
根据提供的解释here。
我了解为什么将值硬编码为8192 。
因此,对于正在对字节数组
parallelSort(byte[])
排序的函数,这是有意义的。您可以将最小并行排序限制保持为8192个值(对于字节数组,每个值= 1个字节)。但是,如果您考虑使用
public static void parallelSort(int[] a)
整数变量的大小为4Bytes(32位)。因此,理想情况下,我们可以在8192个字节中一次将8192/4 = 2048个数字存储在CPU缓存中。
因此,在这种情况下,最小粒度应为2048。
为什么Java中所有的parallelSort函数(例如byte [],int [],long []等)都使用8192作为默认最小值。进行并行排序所需的值数量是多少?
它不应该根据传递给parallelSort函数的类型而有所不同吗?
最佳答案
首先,您似乎误解了链接的说明。 L1数据缓存为32Kb,因此,对于int[]
而言,它非常适合:32768/4=8192
int可以同时放置在L1缓存中。
第二,我认为给出的解释不正确。它专注于指针,因此主要说来是对对象数组进行排序,但是当您比较对象数组中的数据时,始终需要取消引用这些指针以访问实际数据。并且如果您的对象具有非原始字段,则必须进一步取消引用它们。例如,如果对字符串数组进行排序,则不仅要访问数组本身,还必须访问存储在其中的String
对象和char[]
数组。所有这些将需要许多额外的缓存行。
对于此更改,我没有在review thread中找到有关此特定值的任何明确解释。以前是256,后来作为JDK-8014076更新的一部分更改为8192。我认为它只是在某些合理的测试套件上显示了最佳性能。为不同情况设置单独的阈值将增加更多的复杂性。可能的测试表明,它并没有得到返回。请注意,对于Object[]
数组,理想阈值是不可能的,因为比较功能是用户指定的,并且可能具有任意复杂性。对于足够复杂的比较函数,将非常小的数组并行化可能是合理的。