Наш Рехенцентрум збирається купити новий кластер, у зв’язку з чим мене попрохали придумати якісь тести для потенційних постачальників заліза. Так збіглося, що за день до цього я вирішив і собі зробити пару benchmark-ів, як наче знав. Ось що вийшло:

По вертикалі — час виконання завдання у хвилинах, по горизонталі — кількість процесорів. Це два короткі завдання, які я запустив на своєму Core Quad-і. В ідеалі при збільшенні кількості процесорів удвічі час виконання має вдвічі зменшуватися, але так буває лише у казці. Адже час виконання — це:
1. Розбиття завдання на частини, запуск кожної частини на окремому процесорі.
2. Виконання частин завдання паралельно.
3. Результати з кожної частини збираються докупи.
4. Перехід до п. 1.
Деякі задачі можна розбити на незалежні частини, які тільки в самому кінці об’єднуються. Натомість, існують задачі, де частини треба об’єднувати по ходу обчислень, тобто робити багато циклів 1–4. Відтак, маштабування алгоритму залежить від:
1. Типу задачі (тут нічого змінити неможливо);
2. Ефективності алгоритму, тобто прямизни рук програміста. Паралельне програмування — доволі нова й нетривіальна задача, в яку входити, власне, придумати такий алгоритм, який зведе кількість циклів 1—4 до мінімуму;
3. Від компіляторів і стандартних математичних бібліотек. Gcc та вільні бібліотеки типу BLAS та SCALAPACK відсмоктують у компіляторів Інтела та пропрієтарних бібліотек типу MKL або AMD Core Math Library. Ви також можете охуїти від цін на компілятори Портланда, але вони того варті;
4. Від заліза (власне, для цього і тести). Дуже важливо, щоб з’єднання між вузлами було швидким. Потрібен Infiniband, мінімум 10 ґіґабіт/секунду, чим більше, тим краще.
5. Від розміру задачі. Ви помітили, що запуск на 4 процесорах не дає жодного зменшення часу порівняно з 2 процесорами? Пояснення достатньо просте: припустимо, ви навантажили в супермаркеті цілий візок хавчика, і хочете пришвидшити оплату. Ви берете, і розкидаєте продукти відразу на 4 каси. Це вам зекономить час відчутно. Натомість, якщо у вас всього 4 пива, то час, за який ви розкидаєте по одній пляшці на касу, а потім зберете назад, буде такий самий або навіть більший, ніж якщо ви всі 4 пляшки оплатите на одній касі.
Подивимось, для цікавості, benchmark на більшій задачі, де час виконання — це десятки годин:

Як бачите, ця задача дуже добре масштабується до 32 процесорів, а от далі вже хуйово: на 64 процесорах вона виконується за 10 годин, а на 32 — за 12. Нескладно передбачити, що на 128 процесорах час виконання буде лише 9 годин.
Навіщо це знати? Щоб зрозуміти, скільки треба попрохати ресурсів перед запуском задачі. Адже, говорячи про супермаркет, не забуваємо про черги. На всіх кластерах встановлюється хитровиїбана система (Queue Manager), яка розподіляє ресурси між юзерами і слідкує, щоб ніхто не захопив увесь кластер. Ця система конфігурабельна, але загалом вона працює так: коротким завданням дають більший пріоритет в черзі, ніж довгим, навіть якщо вони просять більше ресурсів. У кожного юзера є ліміт на максимальну кількість ядер (у нас це 800), але чим більше просиш, тим довше чекаєш у черзі. Ну бо кластер, як і супермаркет, ніколи не буває вільним:

Циферки — це номер завдання, колонки відповідають процесорам (8 колонок — 8 процесорів — 1 вузол). Наприклад, завдання №1277061 займає 16 процесорів — повністю два вузли node68 i node69. А завдання №1277514 займає три вузли (24 процесори), але не підряд. Вузли 61 і 67 вільні, отже, якщо попрохати 16 процесорів, завдання запуститься відразу. А якщо порохати 64, воно буде чекати, поки звільниться 8 вузлів. Дізнатися скільки чекати — нетривіальна задача, адже кожне завдання розраховане на різний час виконання:

Так виглядає черга завдань на типовому кластері
Літерою R позначено завдання, що виконуються (running), літерою Q — ті, шо в черзі. Там, де виконуються, ви бачите справа дві колонки: час, який попрохав юзер, і час, який вже минув від запуску завдання. Колонка з цифрами від 1 до 5 — це кількість вузлів (множте на 8, отримаєте кількість процесорів). Чи можете ви з цієї статистики дізнатися, коли ж звільняться потрібні вам 128 процесорів? Отож бо, блять. Тому корисно знати про масштабування вашого алгоритму і про те, скільки йому попрохати ресурсів, щоб і в черзі довго не чекати, і виконати завдання швидко.
До речі, те, що хтось попрохав 300 годин, зовсім не означає, що воно буде стільки рахуватися: завдання може завершитися раніше. А от пізніше не може: якщо завдання використало увесь виділений на нього час, менеджер черги його убиває, ібо нєфіг. Добре сконфігурований менеджер також карає мудаків, що просять 300 годин, а юзають з них лише 20: такі будуть чекати в черзі довше.
Зверніть увагу також на колонку з назвою default: як і в супермаркетах бувають каси «для вагітних» чи «для тих, у кого 10 товарів», так і на кластерах бувають черги для коротких завдань (до 10 годин) чи там для довгих завдань (понад 300 годин): адміни для них виділяють окремі вузли. Ну, в нас кластер маленький, на 2000 проців, тому черга одна для всіх.
Попередні пости по темі:
Про суперкомп’ютери: що це та з чим їх їдять
SMP, кластери та ґріди

По вертикалі — час виконання завдання у хвилинах, по горизонталі — кількість процесорів. Це два короткі завдання, які я запустив на своєму Core Quad-і. В ідеалі при збільшенні кількості процесорів удвічі час виконання має вдвічі зменшуватися, але так буває лише у казці. Адже час виконання — це:
1. Розбиття завдання на частини, запуск кожної частини на окремому процесорі.
2. Виконання частин завдання паралельно.
3. Результати з кожної частини збираються докупи.
4. Перехід до п. 1.
Деякі задачі можна розбити на незалежні частини, які тільки в самому кінці об’єднуються. Натомість, існують задачі, де частини треба об’єднувати по ходу обчислень, тобто робити багато циклів 1–4. Відтак, маштабування алгоритму залежить від:
1. Типу задачі (тут нічого змінити неможливо);
2. Ефективності алгоритму, тобто прямизни рук програміста. Паралельне програмування — доволі нова й нетривіальна задача, в яку входити, власне, придумати такий алгоритм, який зведе кількість циклів 1—4 до мінімуму;
3. Від компіляторів і стандартних математичних бібліотек. Gcc та вільні бібліотеки типу BLAS та SCALAPACK відсмоктують у компіляторів Інтела та пропрієтарних бібліотек типу MKL або AMD Core Math Library. Ви також можете охуїти від цін на компілятори Портланда, але вони того варті;
4. Від заліза (власне, для цього і тести). Дуже важливо, щоб з’єднання між вузлами було швидким. Потрібен Infiniband, мінімум 10 ґіґабіт/секунду, чим більше, тим краще.
5. Від розміру задачі. Ви помітили, що запуск на 4 процесорах не дає жодного зменшення часу порівняно з 2 процесорами? Пояснення достатньо просте: припустимо, ви навантажили в супермаркеті цілий візок хавчика, і хочете пришвидшити оплату. Ви берете, і розкидаєте продукти відразу на 4 каси. Це вам зекономить час відчутно. Натомість, якщо у вас всього 4 пива, то час, за який ви розкидаєте по одній пляшці на касу, а потім зберете назад, буде такий самий або навіть більший, ніж якщо ви всі 4 пляшки оплатите на одній касі.
Подивимось, для цікавості, benchmark на більшій задачі, де час виконання — це десятки годин:

Як бачите, ця задача дуже добре масштабується до 32 процесорів, а от далі вже хуйово: на 64 процесорах вона виконується за 10 годин, а на 32 — за 12. Нескладно передбачити, що на 128 процесорах час виконання буде лише 9 годин.
Навіщо це знати? Щоб зрозуміти, скільки треба попрохати ресурсів перед запуском задачі. Адже, говорячи про супермаркет, не забуваємо про черги. На всіх кластерах встановлюється хитровиїбана система (Queue Manager), яка розподіляє ресурси між юзерами і слідкує, щоб ніхто не захопив увесь кластер. Ця система конфігурабельна, але загалом вона працює так: коротким завданням дають більший пріоритет в черзі, ніж довгим, навіть якщо вони просять більше ресурсів. У кожного юзера є ліміт на максимальну кількість ядер (у нас це 800), але чим більше просиш, тим довше чекаєш у черзі. Ну бо кластер, як і супермаркет, ніколи не буває вільним:

Циферки — це номер завдання, колонки відповідають процесорам (8 колонок — 8 процесорів — 1 вузол). Наприклад, завдання №1277061 займає 16 процесорів — повністю два вузли node68 i node69. А завдання №1277514 займає три вузли (24 процесори), але не підряд. Вузли 61 і 67 вільні, отже, якщо попрохати 16 процесорів, завдання запуститься відразу. А якщо порохати 64, воно буде чекати, поки звільниться 8 вузлів. Дізнатися скільки чекати — нетривіальна задача, адже кожне завдання розраховане на різний час виконання:

Так виглядає черга завдань на типовому кластері
Літерою R позначено завдання, що виконуються (running), літерою Q — ті, шо в черзі. Там, де виконуються, ви бачите справа дві колонки: час, який попрохав юзер, і час, який вже минув від запуску завдання. Колонка з цифрами від 1 до 5 — це кількість вузлів (множте на 8, отримаєте кількість процесорів). Чи можете ви з цієї статистики дізнатися, коли ж звільняться потрібні вам 128 процесорів? Отож бо, блять. Тому корисно знати про масштабування вашого алгоритму і про те, скільки йому попрохати ресурсів, щоб і в черзі довго не чекати, і виконати завдання швидко.
До речі, те, що хтось попрохав 300 годин, зовсім не означає, що воно буде стільки рахуватися: завдання може завершитися раніше. А от пізніше не може: якщо завдання використало увесь виділений на нього час, менеджер черги його убиває, ібо нєфіг. Добре сконфігурований менеджер також карає мудаків, що просять 300 годин, а юзають з них лише 20: такі будуть чекати в черзі довше.
Зверніть увагу також на колонку з назвою default: як і в супермаркетах бувають каси «для вагітних» чи «для тих, у кого 10 товарів», так і на кластерах бувають черги для коротких завдань (до 10 годин) чи там для довгих завдань (понад 300 годин): адміни для них виділяють окремі вузли. Ну, в нас кластер маленький, на 2000 проців, тому черга одна для всіх.
Попередні пости по темі:
Про суперкомп’ютери: що це та з чим їх їдять
SMP, кластери та ґріди