Масштабируйте от рабочего стола до кластера

В этом примере показано, как разработать ваш параллельный код MATLAB® по вашей локальной машине и масштабировать до кластера. Кластеры обеспечивают больше вычислительных ресурсов, чтобы убыстриться и распределить ваши расчеты. Можно запустить код в интерактивном режиме параллельно по локальной машине, затем по кластеру, не изменяя код. Когда вы закончите моделируя ваш код по вашей локальной машине, можно разгрузить расчеты к кластеру с помощью пакетных заданий. Так, можно закрыть MATLAB и получить результаты позже.

Разработайте свой алгоритм

Запустите путем прототипирования алгоритма на локальной машине. Пример использует целочисленную факторизацию в качестве демонстрационной проблемы. Это - в вычислительном отношении интенсивная проблема, где сложность факторизации увеличивается с величиной номера. Вы используете простой алгоритм, чтобы разложить на множители последовательность целых чисел.

Создайте вектор из простых чисел в 64-битной точности и умножьте пары простых чисел случайным образом, чтобы получить большие составные числа. Создайте массив, чтобы сохранить результаты каждой факторизации. Код в каждом из следующих разделов в этом примере может занять больше чем 20 min. Чтобы сделать его быстрее, уменьшайте рабочую нагрузку при помощи меньшего количества простых чисел, таких как 2^19. Запуститесь с 2^21 видеть оптимальные итоговые графики.

primeNumbers = primes(uint64(2^21));
compositeNumbers = primeNumbers.*primeNumbers(randperm(numel(primeNumbers)));
factors = zeros(numel(primeNumbers),2);

Используйте цикл, чтобы учесть каждое составное число и измерить время, когда расчет берет.

tic;
for idx = 1:numel(compositeNumbers)
    factors(idx,:) = factor(compositeNumbers(idx));
end
toc
Elapsed time is 684.464556 seconds.

Запустите свой код по локальному параллельному пулу

Parallel Computing Toolbox™ позволяет вам увеличить свой рабочий процесс путем работы нескольких рабочих в параллельном пуле. Итерации в предыдущем for цикл независим, и таким образом, можно использовать parfor цикл, чтобы распределить итерации нескольким рабочим. Просто преобразуйте свой for цикл в parfor цикл. Затем запустите код и измерьте полное время вычисления. Запуски кода в параллельном пуле без дальнейших изменений и рабочие передают ваши расчеты обратно в локальную рабочую область. Поскольку рабочая нагрузка распределяется на нескольких рабочих, время вычисления ниже.

tic;
parfor idx = 1:numel(compositeNumbers)
    factors(idx,:) = factor(compositeNumbers(idx));
end
toc
Elapsed time is 144.550358 seconds.

Когда вы используете parfor и у вас есть Parallel Computing Toolbox, MATLAB автоматически запускает параллельный пул рабочих. Параллельный пул занимает время, чтобы запуститься. Этот пример показывает второй запуск с пулом, уже запущенным.

Кластерным профилем по умолчанию является 'local'. Можно проверять, что этот профиль установлен по умолчанию на вкладке MATLAB Home, параллельно> Выбирают Default Cluster. С этим включенным профилем MATLAB создает рабочих на вашей машине для параллельного пула. Когда вы используете 'local' профиль, MATLAB, по умолчанию, запускает столько же рабочих сколько физические ядра в вашей машине до вашего предпочтительного количества рабочих. Можно управлять параллельным поведением с помощью параллельных настроек. На вкладке MATLAB Home выберите Parallel> Parallel Preferences.

Чтобы измерить ускорение с количеством рабочих, запускайте тот же код несколько раз, ограничивая максимальное количество рабочих. Во-первых, задайте количество рабочих для каждого запуска, до количества рабочих в пуле, и создайте массив, чтобы сохранить результат каждого теста.

numWorkers = [1 2 4 6];
tLocal = zeros(size(numWorkers));

Используйте цикл, чтобы выполнить итерации через максимальное количество рабочих и запустить предыдущий код. Чтобы ограничить количество рабочих, используйте второй входной параметр parfor.

for w = 1:numel(numWorkers)
    tic;
    parfor (idx = 1:numel(compositeNumbers), numWorkers(w))
        factors(idx,:) = factor(compositeNumbers(idx));
    end
    tLocal(w) = toc;
end

Вычислите ускорение путем вычисления отношения между временем вычисления одного рабочего и время вычисления каждого максимального количества рабочих. Чтобы визуализировать, как расчеты масштабируют с количеством рабочих, постройте ускорение против количества рабочих. Заметьте, что ускорение увеличивается с количеством рабочих. Однако масштабирование не совершенно из-за издержек, сопоставленных с распараллеливанием.

f = figure;
speedup = tLocal(1)./tLocal;
plot(numWorkers, speedup);
title('Speedup with the number of workers');
xlabel('Number of workers');
xticks(numWorkers);
ylabel('Speedup');

Когда вы закончите с вашим расчетом, удалите текущий параллельный пул, таким образом, можно создать новый для кластера. Можно получить текущий параллельный пул с gcp функция.

delete(gcp);

Настройте Свой Кластер

Если ваша вычислительная задача является слишком большой или слишком медленной для вашего локального компьютера, можно разгрузить вычисление к локальному кластеру или в облаке. Прежде чем можно будет запустить следующие разделы, необходимо получить доступ к кластеру. На вкладке MATLAB Home перейдите к Параллели>, Обнаруживают, что Кластеры узнают, есть ли у вас уже доступ к кластеру с MATLAB Parallel Server™. Для получения дополнительной информации смотрите, Обнаруживают Кластеры.

Если у вас нет доступа к кластеру, необходимо сконфигурировать доступ к одному, прежде чем можно будет запустить следующие разделы. В MATLAB можно создать кластеры в облачном сервисе, такие как Amazon AWS, непосредственно с Рабочего стола MATLAB. На вкладке Home, в меню Parallel, выбирают Create и Manage Clusters. В Кластерном менеджере по Профилю нажмите Create Cloud Cluster. Чтобы узнать больше об увеличении масштаба к облаку, смотрите Начало работы с Центром Облака. Чтобы узнать больше о ваших опциях для масштабирования к кластеру в вашей сети, смотрите Начало работы с MATLAB Parallel Server (MATLAB Parallel Server).

После того, как вы устанавливаете кластерный профиль, можно изменить его свойства параллельно>, Создают и Управляют Кластерами. Для получения дополнительной информации смотрите, Обнаруживают Кластеры и Профили Кластера Использования. Следующее изображение показывает кластерный профиль в Кластерном менеджере по Профилю:

Запустите свой код по кластерному параллельному пулу

Если вы хотите идти параллельно функции в кластере по умолчанию, установить ваш кластерный профиль по умолчанию параллельно>, Выбирают Default Cluster:

Можно также использовать программируемый подход, чтобы задать кластер. Для этого запустите параллельный пул в кластере путем определения имени кластерного профиля в parpool команда. В следующем коде замените MyCluster с именем вашего кластерного профиля. Также задайте количество рабочих со вторым входным параметром.

parpool('MyCluster',64);
Starting parallel pool (parpool) using the 'MyCluster' profile ...
connected to 64 workers.

Как прежде, мера ускорение с количеством рабочих путем выполнения того же кода несколько раз и ограничения максимального количества рабочих. Поскольку кластер в этом примере допускает больше рабочих, чем локальная настройка, numWorkers может содержать больше значений. Если при запуске этот код, parfor цикл теперь запускается в кластере.

numWorkers = [1 2 4 6 16 32 64];
tCluster = zeros(size(numWorkers));

for w = 1:numel(numWorkers)
    tic;
    parfor (idx = 1:numel(compositeNumbers), numWorkers(w))
        factors(idx,:) = factor(compositeNumbers(idx));
    end
    tCluster(w) = toc;
end

Вычислите ускорение и постройте его против количества рабочих, чтобы визуализировать, как расчеты масштабируют с количеством рабочих. Сравните результаты с теми из локальной настройки. Заметьте, что ускорение увеличивается с количеством рабочих. Однако масштабирование не совершенно из-за издержек, сопоставленных с распараллеливанием.

figure(f);
hold on
speedup = tCluster(1)./tCluster;
plot(numWorkers, speedup);
title('Speedup with the number of workers');
xlabel('Number of workers');
xticks(numWorkers(2:end));
ylabel('Speedup');

Когда вы закончите с вашими расчетами, удалите текущий параллельный пул.

delete(gcp);

Разгрузите и масштабируйте свои расчеты с batch

После того, как вы будете сделаны, моделируя и запускаясь в интерактивном режиме, можно использовать пакетные задания разгрузить выполнение продолжительных расчетов в фоновом режиме с пакетной обработкой данных. Расчет происходит в кластере, и можно закрыть MATLAB и получить результаты позже.

Используйте batch функция, чтобы представить пакетное задание вашему кластеру. Можно поместить содержимое алгоритма в скрипте и использовать batch функция, чтобы представить его. Например, скрипт myParallelAlgorithm выполняет простой сравнительный тест на основе целочисленной задачи разложения на множители, показанной в этом примере. Скрипт измеряет время вычисления нескольких проблемных сложностей с различным количеством рабочих.

Обратите внимание на то, что, если вы отправляете файл скрипта с помощью batch, MATLAB передает все переменные рабочей области кластеру, даже если ваш скрипт не использует их. Если у вас есть большая рабочая область, она влияет негативно на время передачи данных. Как лучшая практика, преобразуйте свой скрипт в файл функции, чтобы избежать этой коммуникации наверху. Можно сделать это путем простого добавления функциональной линии в начале скрипта. Чтобы изучить, как преобразовать myParallelAlgorithm в функцию, см. myParallelAlgorithmFcn.

Следующий код представляет myParallelAlgorithmFcn как пакетное задание. myParallelAlgorithmFcn возвращает два выходных аргумента, numWorkers и time, и необходимо задать 2 как количество выходного входного параметра. Поскольку для кода нужен параллельный пул для parfor цикл, используйте 'Pool' пара "имя-значение" в batch задавать количество рабочих. Кластер использует дополнительного рабочего, чтобы запустить саму функцию. По умолчанию, batch изменяет текущую папку рабочих в кластере к текущей папке клиента MATLAB. Может быть полезно управлять текущей папкой. Например, если ваш кластер использует различную файловую систему, и поэтому пути отличаются, такой как тогда, когда вы подчиняетесь от клиентской машины Windows до кластера Linux. Установите пару "имя-значение" 'CurrentFolder' к папке по вашему выбору, или к '.' постараться не изменять папку рабочих.

totalNumberOfWorkers = 65;
cluster = parcluster('MyCluster');
job = batch(cluster,'myParallelAlgorithmFcn',2,'Pool',totalNumberOfWorkers-1,'CurrentFolder','.');

Чтобы контролировать состояние вашего задания после того, как это будет представлено, откройте Джоба Монитора параллельно> Монитор Джобс. Когда расчеты запускаются в кластере, состоянии смен работы к running:

Можно закрыть MATLAB после того, как задание было представлено. Когда вы открываете MATLAB снова, Монитор Задания отслеживает задание для вас, и можно взаимодействовать с ним, если вы щелкаете правой кнопкой по нему. Например, чтобы получить объект задания, выберите Show Details, и передавать выходные параметры пакетного задания в рабочую область, выбирать Fetch Outputs.

В качестве альтернативы, если вы хотите с блоком MATLAB, пока задание не завершается, используйте wait функция на объекте задания.

wait(job);

Чтобы передать выходные параметры функции от кластера, используйте fetchOutputs функция.

outputs = fetchOutputs(job);
numWorkers = outputs{1};
time = outputs{2};

После получения результатов можно использовать их для вычислений на локальной машине. Вычислите ускорение и постройте его против количества рабочих. Поскольку код запускает факторизации для различных проблемных сложностей, вы получаете график для каждого уровня. Вы видите, что, для каждой проблемной сложности, увеличений ускорения с количеством рабочих, пока издержки для дополнительных рабочих не больше увеличения производительности от распараллеливания. Когда вы увеличиваете проблемную сложность, вы достигаете лучшего ускорения в больших количествах рабочих, потому что наверху связанный с распараллеливанием является менее значительным.

figure
speedup = time(1,:)./time;
plot(numWorkers,speedup);
legend('Problem complexity 1','Problem complexity 2','Problem complexity 3','Problem complexity 4','Location','northwest');
title('Speedup vs complexity');
xlabel('Number of workers');
xticks(numWorkers(2:end));
ylabel('Speedup');

Смотрите также

| | |

Связанные примеры

Больше о