Я хочу отсортировать списки от 1 до 100 миллиардов элементов в системах с 8-128 ядрами, оперативной памятью на 10% элементов и дисками со скоростью 100-1000 МБ / с.
Я протестировал простую сортировку слиянием, где каждое слияние выполняется параллельно процессором:
sorted_part_a:__
\__[CPU.1]__
sorted_part_b:__/ \
\__[CPU.5]__
sorted_part_c:__ / \
\__[CPU.2]__/ \
sorted_part_d:__/ \
\__[CPU.7]
sorted_part_e:__ /
\__[CPU.3]__ /
sorted_part_f:__/ \ /
\__[CPU.6]__/
sorted_part_g:__ /
\__[CPU.4]__/
sorted_part_h:__/
Но есть проблема, связанная с тем, что последний шаг слияния [CPU.7
] имеет делать n сравнений на одном ядре при объединении двух последних входных данных, и сравнение может быть дорогим (подумайте о строках, которые должны соответствовать настройкам локали). В моем тесте [CPU.7
] было узкое место.
Затем я посмотрел на красно-черные деревья. У них есть несколько преимуществ:
- , когда дерево построено, тогда получение отсортированного списка будет
O(n)
без сравнений. Это позволяет избежать узкого места, которое я видел в своем тесте сортировки слиянием. - вы можете строить деревья параллельно и объединять их параллельно , используя несколько ядер.
- вам не нужно все данные, прежде чем вы сможете начать строить деревья (поэтому, если вы читаете с медленного устройства, вы можете сортировать, пока вы читаете, таким образом, не тратя время настенных часов).
Сохранение дерева на диск также кажется довольно просто (просто экспортируйте отсортированный список и высоту дерева), но получение только части дерева с диска кажется более сложным.
Я прочитал Какой алгоритм параллельной сортировки имеет лучшее среднее значение производительность дела? , но, похоже, он игнорирует общий случай с данными среднего размера: эти данные помещаются на диск сервера, но не помещаются в ОЗУ.
Учитывая аппаратное обеспечение (8-128 ядер, ОЗУ для 10% элементов и с дисками, обеспечивающими потоковую передачу 100-1000 МБ / с, 1000 iops), что является самым быстрым способом сортировки списков от 10 ^ 9 до 100 * 10 ^ 9 элементов из 10-100 байт каждый?
С точки зрения непрофессионала:
Какой проверенный и верный способ быстрой сортировки наибольшего объема данных, который вы бы отсортировали на одном сервере?