|
|
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
Здравствуйте. Позвольте задать такой вопрос: Предположим у меня есть прочитанный блок 100Мб в виде массива байт byte[1024 * 1024 * 100]. И есть алгоритм быстрой сортировки (quickSort) - который выполняет сортировку 100Мб за N-секунд. Стоит ли разбивать этот массив на части и сортировать по более мелким кускам (например по 16Кб - сортируем quickSort) а затем использовать сортировку слиянием? Либо особого выигрыша здесь уже не получить, т.к. данные уже в памяти. С другой стороны - на самом деле у меня в памяти 10 блоков по 100Мб. Изначально я планировал создавать 10 потоков, каждый поток будет сортировать свой блок 100Мб. Это позволит эффективнее использовать процессоры. Так вот соль вопроса в том - надо ли дробить сортировку в каждом из блока? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.06.2009, 12:51:13 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
автор Стоит ли разбивать этот массив на части и сортировать по более мелким кускам (например по 16Кб - сортируем quickSort) а затем использовать сортировку слиянием? Либо особого выигрыша здесь уже не получить, т.к. данные уже в памяти. Если сортировать в одном потоке, то не будет вообще никакого выигрыша. Однако если распараллелить сортировку частей, а потом сливать, то ускорение будет (если компьютер с многоядерным процессором или хотя бы процессор с hyperthreading). Однако думаю части должны быть крупными, иначе потребуется много слияний. Например, если процессор 2-ядерный, то разбиваем на 2 части и делаем 1 слияние. Даёт хороший прирост скорости, но с большой оговоркой - если время сортировки частей примерно одинаково, а оно зависит от распределения данных внутри части (это я проводил эксперименты). Для борьбы с этим можно поделить массив на большее число частей, но понадобится больше слияний, то есть их тоже желательно распараллелить по потокам. Порядок слияний влияет на их общую трудоёмкость. Вообще-то уже есть функции сортировки, распараллеленные внутри себя по этому способу - в библиотеке GCC 4.4 есть распараллеленные варианты функций std::sort, std::stable_sort и др. для C++, да и не только в GCC. Кстати, сейчас в стандартный библиотеках компиляторов обычно применяется алгоритм не QuickSort, а IntroSort, но для него справедливы те же выводы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.06.2009, 14:06:29 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
unicornmirage, Алгоритм QuickSort - естественным образом распараллеливается. Если вы этого не понимаете - хреновато вы изучили алгоритм. Сортировка слиянием выигрывает, если НЕТ возможности произвольного доступа к областям памяти - т.е. на файлах. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 11:48:09 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
Сортировка слиянием имеет смысл только при очень больших объёмах, когда не хватает оперативки. В остальных случаях используйте quick sort или "специализированные" методы, которые заточены под статистику ваших данных. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 12:14:43 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
aleks2 Алгоритм QuickSort - естественным образом распараллеливается. Если вы этого не понимаете - хреновато вы изучили алгоритм. хреново он параллелится, между нами девочками ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 12:30:18 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
Gluk (Kazan)aleks2 Алгоритм QuickSort - естественным образом распараллеливается. Если вы этого не понимаете - хреновато вы изучили алгоритм. хреново он параллелится, между нами девочками А вот побить на большие куски, которые сортируются в памяти параллельно, а потом дружненько сливаются - один в один по кнышке ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 12:31:25 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
Может быть он имеет в виду, неравномерность деления медианой? В этом случае один из вычислительных потоков будет "ожидать" другой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 12:38:46 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
maytonМожет быть он имеет в виду, неравномерность деления медианой? В этом случае один из вычислительных потоков будет "ожидать" другой. Полагаю, имелась ввиду возможность сортировать две (а потом четыре и восемь и т.д. сколько процессоров есть) части массива параллельно после разбиения его медианой. Это, как заметил Gluk (Kazan), хреновое распараллеливание :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 12:54:52 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
Gluk (Kazan)хреново он параллелится, между нами девочками Вообще-то я уже ответил. Можно конечно уточнять. Но раз другие не уточняют, то сам это делаю. Алоритм QuickSort распараллеливается хорошо, хотя бы потому,что его формулировка рекурсивная. Но самостоятельная эффективная реализация алгоритма нетривиальна, и нет самысла ею заниматься, можно применить функции сортировки из стандартных библиотек - причём есть как распараллеленные внутри (тогда самому ничего делать не надо), либо взять обычную не распалаллеленную версию и распараллелить самостоятельно. Для этого массив поделить на части, сортировать их параллельно и сливать. При этом возникают проблемы оптимизации, которые я уже описал. Также, как я написал, в нынешних стандарных библиотеках вместо QuickSort обычно используется IntroSort - эта замена сделана для борьбы со "сложным случаем" сортировки в QuickSort, когда её трудоёмкость достигает O(N*N), хотя в среднем она O (N*LOG N). Таким образом, для самостоятельного программирования QuickSort надо разбираться в предмете, но особого смыла оно не имеет. (Для примера, в MS Visual Studio 2008, в библиотеке C++ функции qsort, std::sort и std::stable_sort все реализуют алгоритм IntroSort, ими и пользоваться. Сливать части - функцией std::merge - но это только в C++). На сколько частей разбивать. Независимо от числа частей, в среднем трудоёмкость сортировки составит O(N*LOG N). Но это не значит, что число частей не имеет значения. Потому что надо учесть факторы: - число частей при распараллеливании должно быть не меньше числа потоков выполнения (зависит от числа процессоров, ядер и наличия hyperthreading). Наапример, 2 ядра без hyperthreading - делаем не менее 2 потоков. - но если сделать ровно 2 (как в описанном случае), а распределение значений не случайное, то один поток может закончить работу быстрее, чем второй, и простивать. Поэтому сделать больше - скажем, десяток. Одновременно пусть работают 2 и если один отсортирует свой отрезок, пусть начинает сортировать ещё не сортированный или сливать уже отсортированные. Очень много отрезков делать ни к чему, т.к. оптимизация от равномерной загрузки ядер будет уже небольшая. - Порядок слияния отсортированных частей влияет на трудоёмкость слияния. - Можно попытаться сделать оптимизацию типа "суперлинейный рост скорости". А именно, обычно рост скорости от распараллеливания - медленнее роста числа процессоров (закон Амдаля), но иногда бывает и более быстрым, чем рост числа процессоров (ядер). Это происходит, когда сортируемая часть массива полностью помещается в кеш, относящийся к процееору (ядру). То есть, ориентировочно сотни килобайт. Более мелкие куски массива уже нет смысла делать. Подробнее о "суперлинейном росте скорости" можно ппочитать в документации по организации многопоточной обработки OpenMP, но он - не свойство OpenMP, а свойство архитектуры компьютера. Библиотека OpenMP вообще удобна для распараллеливания сортировки, хотя совершенно необязательна. Вот, написал сколько хватило терпения. Напоследок привожу фрагменты моёй программы сортировки с распараллеливанием на 2 потока функции std::stable_sort (которую легко заменить на любую другую), применяется библиотека OpenMP. Полные примеры для Visual C++ и GCC я уже привёл на форуме ixbt. Пример примитивный - в явном виде задаются 2 потока, для демонстрации идеи. Библиотека OpenMP позволяет легко задавать число потоков динамически (что и следовало бы сделать в практической программе). Но демонстрация возможностей OpenMP не являлась задачей. Пример. Определение массива (можно заменить на любое другое): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. Сортирующий фрагмент кода: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 22:45:13 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
Partisan MАлоритм QuickSort распараллеливается хорошо, хотя бы потому,что его формулировка рекурсивная. С каких это пор рекурсивность стала признаком хорошей распараллеливаемости? Он распараллеливается хоть как-то (плохенько) только благодаря тому, что рекурсивный вызов - двойной, после разбиения медианой получившиеся две части можно сортировать независимо. Рекурсия тут ни при чем совершенно. Partisan MТакже, как я написал, в нынешних стандарных библиотеках вместо QuickSort обычно используется IntroSort - эта замена сделана для борьбы со "сложным случаем" сортировки в QuickSort, когда её трудоёмкость достигает O(N*N), хотя в среднем она O (N*LOG N). Таким образом, для самостоятельного программирования QuickSort надо разбираться в предмете, но особого смыла оно не имеет. (Для примера, в MS Visual Studio 2008, в библиотеке C++ функции qsort, std::sort и std::stable_sort все реализуют алгоритм IntroSort, ими и пользоваться. Сливать части - функцией std::merge - но это только в C++). Для примера в .NET - quicksort, причем с выбором pivot по среднему индексу xD Вот некоторые люди напарываются))) Partisan MНезависимо от числа частей, в среднем трудоёмкость сортировки составит O(N*LOG N). ё, да это и ежу ясно, что распараллеивание не влияет на сложность (характер роста), алгоритм-то тот же самый, но оно влияет на коэффициент с этом самом "О-большое", n*logn и n*logn/16 - разные вещи таки, хотя и то и другое O(n*logn) :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2009, 23:03:56 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
чё то бред какой-то с этим "распараллеливанием" Параллелются солдаты прочесывающие лес в поисках чего-то но не сортировка Сортировка -- это не поиск чего-то, это процесс, его надо пройти до конца. Какая хрен разница сколько у тебя процессоров, 1, 2, 4, 256 Технически могут быть разные отклонения, туда-сюда, но очень незначительные. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2009, 03:16:31 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
ну может быть sort , stable_sort где-то там и скрещиваются и интеллектуизируются А может и sort() -- это совсем не хоаровский qsort. Мне это до лампочки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2009, 03:23:54 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
На дурацкие комментарии отвечать не буду. Нет ничего настолько простого, чтобы не нашёлся кто-нибудь, неспособный это понять. В общем, я описал распараллеливание сортировки довольно подробно. Может, кому-нибудь поможет. А если кому не поможет, то пусть это будет его проблемой. Да, по OpenMP можно найти книжки на английском языке и много статей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2009, 06:44:24 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
Partisan MНа дурацкие комментарии отвечать не буду. Нет ничего настолько простого, чтобы не нашёлся кто-нибудь, неспособный это понять. В общем, я описал распараллеливание сортировки довольно подробно. Может, кому-нибудь поможет. А если кому не поможет, то пусть это будет его проблемой. Да, по OpenMP можно найти книжки на английском языке и много статей. ну зачем это называть распараллеливанием? Это совсем из другой оперы. И твою идею из первого поста я прекрасно понял: но тут надо проверять, тут хер знает сколько нюансов На одних данных может быть так, на других по-другому Ты же сам не собираешься случай: разобьем всё на пары (сделаем своп), отсортируем мерджем потом Да это глупо всё и бесполезно и непонятно куда ты это хочешь прилепить и зачем И 100 мб -- это копейки ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2009, 07:05:47 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
Забудь ваще это слово -- "распараллеливание". Это ламерское слово. У людей есть только одна ось Времени. У нас нет двух осей Времени и не будет, хоть ты тресни. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2009, 07:19:46 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
RT183Забудь ваще это слово -- "распараллеливание". Это ламерское слово. У людей есть только одна ось Времени. У нас нет двух осей Времени и не будет, хоть ты тресни. Глупость какая. У нас есть много вычислительных элементов и одна задача, вот что важно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2009, 09:06:51 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
Partisan MGluk (Kazan)хреново он параллелится, между нами девочками Вообще-то я уже ответил. Можно конечно уточнять. Но раз другие не уточняют, то сам это делаю. Алоритм QuickSort распараллеливается хорошо ... Бла Бла Бла не относящееся к проблеме распараллеливания QuickSort ... Вообще то тут об этом уже сказали, но я тоже скажу :) Безусловно существуют алгоритмы сортировки, специально разработанные для того, чтобы их параллелить, но именно QuickSort к ним определенно не относится, какой бы он рекурсивный там не был Дело в том, что кусочки массива, которые он отдает на сортировку своим рекурсивным вызовам оччень разные по размеру, в некоторых реализациях они сильно разные даже на одном уровне рекурсии, а для распараллеливания это ... несколько неудобно. И вообще параллелить дерево рекурсивных вызовов ... В общем вы понимаете (с) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2009, 09:48:23 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
Gluk (Kazan) Дело в том, что кусочки массива, которые он отдает на сортировку своим рекурсивным вызовам оччень разные по размеру, в некоторых реализациях они сильно разные даже на одном уровне рекурсии, а для распараллеливания это ... несколько неудобно. И вообще параллелить дерево рекурсивных вызовов ... Думаю, что распараллелить всё-таки можно, но насколько будет это эффективно? Если прирост будет порядка 10-15% то не стоит связываться. В любом случае, нам нужны цифры. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2009, 10:04:53 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
maytonGluk (Kazan) Дело в том, что кусочки массива, которые он отдает на сортировку своим рекурсивным вызовам оччень разные по размеру, в некоторых реализациях они сильно разные даже на одном уровне рекурсии, а для распараллеливания это ... несколько неудобно. И вообще параллелить дерево рекурсивных вызовов ... Думаю, что распараллелить всё-таки можно, но насколько будет это эффективно? Если прирост будет порядка 10-15% то не стоит связываться. В любом случае, нам нужны цифры. Можно конечно (раздел 1.5) только не лучшая эта задача для распараллеливания. И QuickSort на больших объемах не лучший выбор (а на небольших нефих его параллелить). При том что лучшее решение лежит на поверхности, говорить о том, что QuickSort паралелится моветон :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2009, 10:18:44 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
Я читал Грегори Эндрюса, вот только не помню, чтобы он там описывал сортирующие алгоритмы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2009, 11:50:17 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
maytonЯ читал Грегори Эндрюса, вот только не помню, чтобы он там описывал сортирующие алгоритмы. Упоминается QuickSort, но описывается адаптивная квадратура. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.06.2009, 12:22:17 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
Gluk (Kazan)Partisan MGluk (Kazan)хреново он параллелится, между нами девочками Вообще-то я уже ответил. Можно конечно уточнять. Но раз другие не уточняют, то сам это делаю. Алоритм QuickSort распараллеливается хорошо ... Бла Бла Бла не относящееся к проблеме распараллеливания QuickSort ... Вообще то тут об этом уже сказали, но я тоже скажу :) Безусловно существуют алгоритмы сортировки, специально разработанные для того, чтобы их параллелить, но именно QuickSort к ним определенно не относится, какой бы он рекурсивный там не был Дело в том, что кусочки массива, которые он отдает на сортировку своим рекурсивным вызовам оччень разные по размеру, в некоторых реализациях они сильно разные даже на одном уровне рекурсии, а для распараллеливания это ... несколько неудобно. И вообще параллелить дерево рекурсивных вызовов ... В общем вы понимаете (с) Если вы не умеете параллелить, это еще не означает что "оно плохо параллелится". Признаком ХОРОШЕЙ параллельности является исключительно наличие операций НЕЗАВИСИМЫХ от других. QSort порождает такие операции - деление медианой массива. Я, канешно, понимаю что НЕРЕКУРСИВНАЯ реализация QSort для вас загадка, но поверьте: рекурсия НЕ обязательна. В этом случае порождается очередь запросов на сортировку которую можно обрабатывать во столько потоков, сколько у вас есть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2009, 09:26:40 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
aleks2 Если вы не умеете параллелить, это еще не означает что "оно плохо параллелится". Признаком ХОРОШЕЙ параллельности является исключительно наличие операций НЕЗАВИСИМЫХ от других. QSort порождает такие операции - деление медианой массива. Я, канешно, понимаю что НЕРЕКУРСИВНАЯ реализация QSort для вас загадка, но поверьте: рекурсия НЕ обязательна. В этом случае порождается очередь запросов на сортировку которую можно обрабатывать во столько потоков, сколько у вас есть. Друг мой, рекурсия для меня не загадка (также как и то что любой рекурсивный алгоритм можно перевести в итеративную форму), но суть не в этом. Для того, чтобы задачка ХОРОШО (а не просто абы как) параллелилось, желательно чтобы параллельные процессы выполняли по возможности одинаковый объем работ, в противном случае, издержки на управление, синхронизацию и т.п. убьют на корню все бенефиты, которые даст нам распараллеливание. В случае QuickSort это не так, размеры сортируемых регионов уменьшаются на каждом уровне рекурсии, более того, поскольку медиану искать весьма накладно (и это тоже дополнительные издержки на реализацию хорошей многопоточности), в большинстве случаев в качестве "медианы" берется первый попавшийся элемент, и как следствие половинки становятся очень неодинаковы В общем меня несколько утомила эта дискуссия и продолжение ее я предлагаю вести в следующей форме: 1. Вы предоставляете свою версию параллельного QuickSort (ну скажем на 8 процессоров на 100000 элементов) 2. Я реализую кондовый однопоточный рекурсивный QuickSort, ага 3. Сравниваем производительность, на моем железе 4. Я кричу "Шайтан" и рву на себе волосы, поскольку ваш вариант работает быстрее в N раз так пойдет ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2009, 10:44:01 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
Gluk (Kazan)... +1 Я тоже хотел-бы увидеть сравнительный тест. Только 8 процессов - это слишком. Сделать хотя-бы 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2009, 10:47:03 |
|
||
|
Сортировка блока в памяти 100Мб quick sort vs сортировка слиянием
|
|||
|---|---|---|---|
|
#18+
maytonGluk (Kazan)... +1 Я тоже хотел-бы увидеть сравнительный тест. Только 8 процессов - это слишком. Сделать хотя-бы 2. На 2 вообще понту нет (особенно ядрах) 256 процов не обещаю, но уж 8 и память чтобы лям int-ов влезло можно пошукать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.06.2009, 10:59:42 |
|
||
|
|

start [/forum/topic.php?fid=16&msg=36041155&tid=1344373]: |
0ms |
get settings: |
6ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
25ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
57ms |
get tp. blocked users: |
1ms |
| others: | 185ms |
| total: | 306ms |

| 0 / 0 |
