Цей контент є частиною серії: Розподілені обчислення
Слідкуйте за виходом нових статей цієї серії.
1. Введення
API взаємодії
Для платформи BOINC розробники надають документовані інтерфейси API, призначені для взаємодії з додатками і web-сайтами. Можливості, що надаються цими інтерфейсами, включають в себе:
- локальний і віддалений контроль графічного інтерфейсу клієнта BOINC;
- надання інформації про набраних кредитах (в цілому по проекту, для окремого користувача, команди або країни);
- управління обліковими записами декількох проектів через єдиний web-інтерфейс;
- сумарна статистика по кредитах для хостів, команд і користувачів, що беруть участь в декількох проектах;
- механізми, що дозволяють локальним програмам редагувати настройки клієнта BOINC.
2. Найпростіший приклад розподіленого додатка
Перший приклад, який ми будемо розглядати можна знайти серед вихідних кодів Boinc в каталозі samples / example_app. Цей приклад є найпростіше однопоточні додаток BOINC. Програма виконує просту роботу (наприклад, перевірку), яка може бути завершена або успішно, або невдало. Приклад можна використовувати як основу для власних додатків - потрібно лише замінити реалізацією власного алгоритму ту частину, яка відноситься до обчислень.
Вихідний код прикладу розбитий на заголовки, два файли з кодом і Makefile для збірки проекту (не вважаємо файли, що містять суфікс «mac»):
Далі ми докладніше вивчимо вихідний текст програми-прикладу. Однак краще мати перед очима оригінальний вихідний файл - окремі фрагменти і незначущі для цілей вивчення BOINC блоки коду ми будемо пропускати або розглядати в іншому порядку. Серед усього іншого будуть пропущені ті частини, які пов'язані з взаємодією процесів в рамках одного комп'ютера і весь висновок графіки. Ні в тому, ні в іншому немає особливостей, пов'язаних з BOINC. У розділі 2.3 дана таблиця функцій API BOINC, використовуваних в програмі. До цієї таблиці можна звертатися в міру появи в вихідному коді відповідних функцій (в тексті статті вони будуть виділені курсивом).
2.1 Програма-приклад UpperCase
Програми на мовах, відмінних від C / C ++
Існують більш-менш прості способи використання інших мов програмування, крім базових для BOINC-додатків C і C ++. Розробниками описані «трюки» для наступних мов:
Основний код додатка міститься в файлі uc2.cpp, програма переводить текст вхідного файлу в верхній регістр. Для демонстрації можливостей BOINC, розробники програми реалізували обробку такої команди:
- run_slow. додаток «засинає» на 1 секунду після кожного обробленого символу;
- cpu_time N. по завершенні обробки програма додатково використовує N секунд часу процесора;
- early_exit. примусове завершення програми після обробки 30 символів;
- early_crash. аварійне завершення програми після обробки 30 символів;
- early_sleep. програма «засинає» після обробки 30 символів.
Природно, вихідний код програми починається з підключення заголовних файлів:
Потім підключаються різні заголовки платформи, що містять визначення функцій API BOINC.
Всі зазначені заголовки (за винятком стандартних для C ++) в каталозі вихідних кодів BOINC знаходяться в підкаталогах lib і api. Там же можна знайти безліч визначень (і реалізацій) інших функцій API BOINC.
Програма працює з трьома файлами: вхідним файлом з вихідним текстом, вихідним файлом, в який буде записаний результат, і допоміжним файлом для підрахунку кредитів. Їх імена (логічні) визначаються у вихідному коді:
Тепер перейдемо до основної функції програми.
В якості підготовчого етапу необхідно ініціалізувати підсистему BOINC. У нашому випадку проводиться ініціалізація однопоточному програми:
Важлива особливість розробки додатків під платформу BOINC - це робота з файлами. Як уже згадувалося раніше (див. Статтю 2 «Архітектура домашніх високопродуктивних обчислень»), додатки BOINC працюють з логічними іменами файлів, а для перетворення логічного імені в фізичне використовуються спеціальні функції. Далі в вихідному коді нашого прикладу якраз демонструється робота з файлами.
Для читання відкривається вхідний файл. Функція boinc_resolve_filename використовується, щоб визначити фізичний шлях до файлу, заданому логічним ім'ям INPUT_FILENAME:
Потім відкривається для читання файл, розташований по з'ясування раннє фізичній шляху:
Той же алгоритм використовується для відкриття вихідного і допоміжного файлів, однак, логіка роботи програми вимагає деяких додаткових дій.
Необхідність залучення допоміжного файлу визначається самою суттю «volunteer computing». Програма (клієнт BOINC) могла бути завершена до закінчення розрахунку завдання. Однак було б нерозумним в цьому випадку починати всю роботу заново (особливо, якщо для завершення потрібно кілька годин безперервних обчислень). Для відновлення поточного стану використовується допоміжний файл:
Читаємо з допоміжного файлу число вже оброблених символів:
Пропускаємо у вхідному файлі все оброблені символи:
«Обрізаємо» вихідний файл за кількістю оброблених символів (в іншому випадку при аварійному завершенні роботи - наприклад, при виключенні живлення або «зависання» операційної системи - в вихідному файлі може виявитися ще Непосчітанние оброблений символ, що призведе до отримання неправильного результату!):
Для роботи з вихідним файлом розробники вважали більш зручним використовувати клас MFILE (якого належить змінна out) - він визначений в файлі lib / mfile.h.
Нарешті, коли виконана вся підготовча робота, настав час основного циклу програми:
Якщо в командному рядку було вказано будь-якої з параметрів (див. Вище), то програма модифікує свою поведінку:
Збереження поточного стану виконується за допомогою періодичного виклику функції API BOINC boinc_time_to_checkpoint (). Ця функція, звіряючись з використанням режиму розширеного клієнта BOINC, визначає настав час для фіксації проміжних результатів роботи (тоді в нашій програмі викликається функція do_checkpoint).
Функція do_checkpoint записує у допоміжний файл кількість оброблених символів.
Клієнт інформується про завершення збереження стану (проміжних результатів) за допомогою виклику функції boinc_checkpoint_completed ():
Тепер звітуємо про прогрес виконання завдання - передане клієнтові значення буде відображатися як відсоток виконання роботи.
Згідно налаштувань (див. Вище, де написано про параметри командного рядка), витратимо трохи машинного часу «даремно». Зауважте, що при цьому ми не забуваємо оновлювати інформацію про відсоток виконання роботи!
Функція do_a_giga_flop виконує трильйон операцій з плаваючою комою (Gflop).
Завдання виконано на 100%
Завершуємо роботу додатка BOINC
Після закінчення роботи клієнт BOINC самостійно зв'яжеться з сервером, передасть йому результати роботи і запросить нове завдання.
2.2 Структура програми BOINC
Тепер повернемося до структури стандартного додатка. Перша функція API BOINC, яка може бути викликана в програмі, - це функція ініціалізації boinc_init (). Відповідно, завершитися додаток має функцією boinc_finish (). У процесі роботи необхідно оновлювати інформацію про ступінь виконання завдання (функція boinc_fraction_done ()) і зберігати результати проміжних обчислень (зв'язка boinc_time_to_checkpoint () і boinc_checkpoint_completed ()).
При розробці програми для платформи BOINC необхідно також пам'ятати про особливості роботи з файлами і акуратності при відновленні проміжних результатів обчислень.
2.3 Функції API BOINC
У цьому розділі представлений список функцій API BOINC, що зустрічалися в програмі-прикладі.
Таблиця 1. Список використаних функцій API BOINC
int boinc_finish (int status)
Функція повинна бути викликана по завершенні програми. Ненульовий статус говорить про помилку.
3. Висновок
У цій статті ми розглянули простий приклад розподіленого додатка, призначеного для виконання на базі платформи BOINC. Приклад поставляється з вихідними кодами проекту BOINC і демонструє базову архітектуру і функції. Цей проект можна використовувати як основу для створення розподілених додатків, нескладних алгоритмічно, але вимагають великих обчислювальних ресурсів.
Як бачите, немає нічого складного в створенні додатків, здатних використовувати розподілену структуру обчислювачів. Всю основну частину роботи бере на себе платформа BOINC: на серверної частини вона розподіляє завдання між клієнтами, а клієнт запускає завдання на виконання і звітує перед сервером (а попутно ще й відображає користувачеві хід виконання роботи). Однак до сих пір наш клієнт BOINC виконував одне-єдине завдання. Як же зробити велику кількість завдань? У наступній статті буде розказано про те, як автоматизувати процес генерації робочих завдань для програми.