Когда вы распределяете массив многим рабочим, MATLAB делит массив в сегменты и присваивает один сегмент массива каждому рабочему. Можно разделить двумерный массив горизонтально, присвоив столбцы исходного массива различным рабочим, или вертикально, путем присвоения строк. Массив с размерностями N может быть разделен по любому из его измерений N. Вы выбираете, какая размерность массива должна быть разделена путем определения его в команде конструктора Array.
Например, чтобы распределить 80 1000 массив четырем рабочим, можно разделить его или столбцами, дав каждому рабочему 80 250 сегмент, или строками, с каждым рабочим, добирающимся 20 1000 сегмент. Если измерение массива не делится равномерно по количеству рабочих, MATLAB делит его максимально равномерно.
Следующий пример создает 80 1000 реплицированный массив и присваивает его переменной A
. При этом каждый рабочий создает идентичный массив в его собственной рабочей области и присваивает его переменной A
, где A
локально для того рабочего. Вторая команда распределяет A
, создание сингла 80 1000 массив D
это охватывает все четырех рабочих. Рабочий 1 столбец 1 - 250 хранилищ, рабочий 2 столбца 251 - 500 хранилищ, и так далее. Распределение по умолчанию является последней неодноэлементной размерностью, таким образом, столбцами в этом случае 2-мерного массива.
spmd A = zeros(80, 1000); D = codistributed(A) end Lab 1: This lab stores D(:,1:250). Lab 2: This lab stores D(:,251:500). Lab 3: This lab stores D(:,501:750). Lab 4: This lab stores D(:,751:1000).
У каждого рабочего есть доступ ко всем сегментам массива. Доступ к локальному сегменту быстрее, чем к удаленному сегменту, потому что последний требует отправки и получения данных между рабочими и таким образом занимает больше времени.
Для каждого рабочего Командное окно Параллели MATLAB отображает информацию о codistributed массиве, локальном фрагменте и codistributor. Например, 8 8 единичная матрица codistributed среди четырех рабочих, с двумя столбцами на каждом рабочем, отображается как это:
>> spmd II = eye(8,'codistributed') end Lab 1: This lab stores II(:,1:2). LocalPart: [8x2 double] Codistributor: [1x1 codistributor1d] Lab 2: This lab stores II(:,3:4). LocalPart: [8x2 double] Codistributor: [1x1 codistributor1d] Lab 3: This lab stores II(:,5:6). LocalPart: [8x2 double] Codistributor: [1x1 codistributor1d] Lab 4: This lab stores II(:,7:8). LocalPart: [8x2 double] Codistributor: [1x1 codistributor1d]
Чтобы видеть фактические данные в локальном сегменте массива, используйте getLocalPart
функция.
В распределении массива N
строки, если N
является равномерно делимым количеством рабочих, MATLAB хранит одинаковое число строк (N/numlabs
) на каждом рабочем. Когда этот номер не является равномерно делимым количеством рабочих, MATLAB делит массив максимально равномерно.
MATLAB обеспечивает codistributor свойства объектов под названием Dimension
и Partition
то, что можно использовать, чтобы определить точное распределение массива. Смотрите Индексацию в Массив Codistributed для получения дополнительной информации об индексации с codistributed массивами.
Можно распределить массивы любого MATLAB встроенный тип данных, и также числовые массивы, которые являются комплексными или разреженными, но не массивы указателей на функцию или типов объектов.
Можно создать codistributed массив любым из следующих способов:
Разделение Большего Массива — Запускается с большого массива, который реплицирован во всех рабочих, и разделите его так, чтобы части были распределены на рабочих. Это является самым полезным, когда у вас есть достаточная память, чтобы сохранить реплицированный массив начальной буквы.
Создание от Меньших массивов — Запускается с меньших различных или реплицированных массивов, сохраненных на каждом рабочем, и комбинирует их так, чтобы каждый массив стал сегментом большего codistributed массива. Этот метод уменьшает требования к памяти, когда он позволяет вам создать codistributed массив из мелких кусочков.
Используя Функции конструктора MATLAB — Использование любая из функций конструктора MATLAB как rand
или zeros
с codistributor возражают аргументу. Эти функции предлагают быстрые средние значения построения codistributed массива любого размера всего на одном шаге.
Если у вас уже есть большой массив в памяти, что вы хотите MATLAB к процессу более быстро, можно разделить его в меньшие сегменты и распределить эти сегменты всем рабочим, использующим codistributed
функция. У каждого рабочего затем есть массив, который является частью размер оригинала, таким образом уменьшая время, требуемое получить доступ к данным, которые локальны для каждого рабочего.
Как простой пример, следующая строка кода создает 4 8 реплицированную матрицу на каждом рабочем, присвоенном переменной A
:
spmd, A = [11:18; 21:28; 31:38; 41:48], end A = 11 12 13 14 15 16 17 18 21 22 23 24 25 26 27 28 31 32 33 34 35 36 37 38 41 42 43 44 45 46 47 48
Следующая строка использует codistributed
функционируйте, чтобы создать сингл 4 8 матричный D
это распределяется вдоль второго измерения массива:
spmd D = codistributed(A); getLocalPart(D) end 1: Local Part | 2: Local Part | 3: Local Part | 4: Local Part 11 12 | 13 14 | 15 16 | 17 18 21 22 | 23 24 | 25 26 | 27 28 31 32 | 33 34 | 35 36 | 37 38 41 42 | 43 44 | 45 46 | 47 48
Массивы A
и D
одного размера (4 8). Массив A
существует в его полном размере на каждом рабочем, в то время как только сегмент массива D
существует на каждом рабочем.
spmd, size(A), size(D), end
Исследуя переменные в клиентской рабочей области, массив, который является codistributed среди рабочих в spmd
оператор, распределенный массив с точки зрения клиента вне spmd
оператор. Переменными, которые не являются codistributed в spmd, являются Составные объекты в клиенте вне spmd.
whos Name Size Bytes Class A 1x4 613 Composite D 4x8 649 distributed
Смотрите codistributed
страница ссылки на функцию для синтаксиса и информации об использовании.
codistributed
функция менее полезна для сокращения объема памяти, требуемого хранить данные, когда вы сначала создаете полный массив в одной рабочей области и затем делите его в распределенные сегменты. Чтобы экономить на памяти, можно создать мелкие кусочки (локальная часть) на каждом рабочем сначала, и затем использовать codistributed.build
объединить их в единый массив, который распределяется на рабочих.
Этот пример создает 4 250 различный массив на каждом из четырех рабочих и затем использует codistributor
распределить эти сегменты на четырех рабочих, создавая 4 1000 codistributed массив. Вот различный массив, A
:
spmd A = [1:250; 251:500; 501:750; 751:1000] + 250 * (labindex - 1); end WORKER 1 WORKER 2 WORKER 3 1 2 ... 250 | 251 252 ... 500 | 501 502 ... 750 | etc. 251 252 ... 500 | 501 502 ... 750 | 751 752 ...1000 | etc. 501 502 ... 750 | 751 752 ...1000 | 1001 1002 ...1250 | etc. 751 752 ...1000 | 1001 1002 ...1250 | 1251 1252 ...1500 | etc. | | |
Теперь объедините эти сегменты в массив, который распределяется первой размерностью (строки). Массив теперь 16 250, с 4 250 сегмент, находящийся на каждом рабочем:
spmd D = codistributed.build(A, codistributor1d(1,[4 4 4 4],[16 250])) end Lab 1: This lab stores D(1:4,:). LocalPart: [4x250 double] Codistributor: [1x1 codistributor1d] whos Name Size Bytes Class A 1x4 613 Composite D 16x250 649 distributed
Вы могли также использовать реплицированные массивы тем же способом, если бы вы хотели создать codistributed массив, сегменты которого были все идентичны, чтобы запуститься с. Смотрите codistributed
страница ссылки на функцию для синтаксиса и информации об использовании.
MATLAB обеспечивает несколько функций конструктора Array, которые можно использовать, чтобы создать codistributed массивы определенных значений, размеров и классов. Эти функции действуют таким же образом в качестве своих нераспределенных дубликатов на языке MATLAB, за исключением того, что они распределяют результирующий массив на рабочих, использующих заданный объект codistributor, codist
.
Функции конструктора. codistributed функции конструктора перечислены здесь. Используйте codist
аргумент (созданный codistributor
функция: codist=codistributor()
) задавать по который размерность распределить массив. Смотрите отдельные страницы с описанием для этих функций для дальнейшего синтаксиса и информации об использовании.
eye
(___,codist)false
(___,codist)Inf
(___,codist)NaN
(___,codist)ones
(___,codist)rand
(___,codist)randi
(___,codist)randn
(___,codist)true
(___,codist)zeros
(___,codist)codistributed.cell
(m,n,...,codist)codistributed.colon
(a,d,b) codistributed.linspace
(m,n,...,codist) codistributed.logspace
(m,n,...,codist)sparse
(m,n,codist)codistributed.speye
(m,...,codist)codistributed.sprand
(m,n,density,codist)codistributed.sprandn
(m,n,density,codist)
Та часть codistributed массива, который находится на каждом рабочем, является частью большего массива. Каждый рабочий может работать над его собственным сегментом обычного массива, или он может сделать копию того сегмента в различном или частном собственном массиве. Эта локальная копия codistributed сегмента массивов называется локальным массивом.
getLocalPart
функционируйте копирует сегменты codistributed массива к отдельному различному массиву. Этот пример делает локальную копию L
из каждого сегмента codistributed массива D
. Размер L
показывает, что это содержит только локальную часть D
для каждого рабочего. Предположим, что вы распределяете массив на четырех рабочих:
spmd(4) A = [1:80; 81:160; 161:240]; D = codistributed(A); size(D) L = getLocalPart(D); size(L) end
возвращается на каждом рабочем:
3 80 3 20
Каждый рабочий распознает что codistributed массив D
3 80. Однако заметьте что размер локальной части, L
, находится 3 20 на каждом рабочем, потому что 80 столбцов D
распределяются по четырем рабочим.
Используйте codistributed.build
функция, чтобы выполнить противоположную операцию. Эта функция, описанная в Создании от Меньших массивов, комбинирует локальные различные массивы в единый массив, распределенный в заданном измерении.
При продолжении предыдущего примера возьмите локальные различные массивы L
и соединенный их как сегменты, чтобы создать новый codistributed массив X
.
spmd codist = codistributor1d(2,[20 20 20 20],[3 80]); X = codistributed.build(L,codist); size(X) end
возвращается на каждом рабочем:
3 80
MATLAB предлагает несколько функций, которые предоставляют информацию о каком-то конкретном массиве. В дополнение к этим стандартным функциям существует также две функции, которые полезны только с codistributed массивами.
iscodistributed
функция возвращает логический 1
TRUE
) если входной массив является codistributed и логическим 0
ложь
) в противном случае. Синтаксис
spmd, TF = iscodistributed(D), end
где D
любой массив MATLAB.
Объект codistributor определяет, как массив разделен и его размерность распределения. Чтобы получить доступ к codistributor массива, используйте getCodistributor
функция. Это возвращает два свойства, Dimension
и Partition
:
spmd, getCodistributor(X), end Dimension: 2 Partition: [20 20 20 20]
Dimension
значение 2
означает массив X
распределяется столбцами (размерность 2); и Partition
значение [20 20 20 20]
средние значения, что двадцать столбцов находятся на каждом из этих четырех рабочих.
Чтобы получить эти свойства программно, возвратите выходной параметр getCodistributor
к переменной затем используйте запись через точку, чтобы получить доступ к каждому свойству:
spmd C = getCodistributor(X); part = C.Partition dim = C.Dimension end
Другие функции, которые предоставляют информацию о стандартных массивах также, работают над codistributed массивами и используют тот же синтаксис.
При построении массива вы распределяете части массива по одному из измерений массива. Можно изменить направление этого распределения на существующем массиве с помощью redistribute
функция с различным объектом codistributor.
Создайте 8 16 codistributed массив D
из случайных значений, распределенных столбцами на четырех рабочих:
spmd D = rand(8,16,codistributor()); size(getLocalPart(D)) end
возвращается на каждом рабочем:
8 4
Создайте новый codistributed массив, распределенный строками от существующей, уже распределенной столбцами:
spmd X = redistribute(D, codistributor1d(1)); size(getLocalPart(X)) end
возвращается на каждом рабочем:
2 16
Можно восстановить codistributed массив к его нераспределенной форме с помощью gather
функция. gather
берет сегменты массива, которые находятся на различных рабочих, и комбинирует их в реплицированный массив на всех рабочих, или в единый массив на одном рабочем.
Распределите 4 10 массив четырем рабочим вдоль второго измерения:
spmd, A = [11:20; 21:30; 31:40; 41:50], end A = 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 spmd, D = codistributed(A), end WORKER 1 WORKER 2 WORKER 3 WORKER 4 11 12 13 | 14 15 16 | 17 18 | 19 20 21 22 23 | 24 25 26 | 27 28 | 29 30 31 32 33 | 34 35 36 | 37 38 | 39 40 41 42 43 | 44 45 46 | 47 48 | 49 50 | | | spmd, size(getLocalPart(D)), end Lab 1: 4 3 Lab 2: 4 3 Lab 3: 4 2 Lab 4: 4 2
Восстановите нераспределенные сегменты к полной форме массивов путем сбора сегментов:
spmd, X = gather(D), end X = 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 spmd, size(X), end 4 10
В то время как индексация в нераспределенный массив является довольно прямой, codistributed массивы требуют дополнительных факторов. Каждая размерность нераспределенного массива индексируется в диапазоне 1 к итоговому индексу, который представлен в MATLAB end
ключевое слово. Длина любой размерности может быть легко определена с помощью любого size
или length
функция.
С codistributed массивами так легко не получены эти значения. Например, второй сегмент массива (то, что находится в рабочей области рабочего 2) имеет начальное значение индекса, которое зависит от распределения массивов. Для 200 1000 массива с распределением по умолчанию столбцами более чем четыре рабочих, начальное значение индекса на рабочем 2 251. Для 1000 200 массива, также распределенного столбцами, тот же самый индекс был бы 51. Что касается конечного индекса, это не дано при помощи end
ключевое слово, как end
в этом случае относится в конец целого массива; то есть, последний индекс итогового сегмента. Длина каждого сегмента также не дана при помощи length
или size
функции, когда они только возвращают длину целого массива.
colon
MATLAB оператор и
end
ключевое слово является двумя из основных инструментов для индексации в нераспределенные массивы. Для codistributed массивов MATLAB обеспечивает версию colon
оператор, названный codistributed.colon
. Это на самом деле - функция, не символьный оператор как colon
.
При использовании массивов, чтобы индексировать в codistributed массивы, можно использовать только реплицированные или codistributed массивы в индексации. Тулбокс не проверяет, чтобы гарантировать, что индекс реплицирован, когда это потребовало бы глобальной связи. Поэтому использование неподдерживаемых вариантов (таких как labindex
) индексировать в codistributed массивы может создать неожиданные результаты.
Предположим, что у вас есть вектор-строка из 1 миллиона элементов, распределенных среди нескольких рабочих, и вы хотите определить местоположение его элемента номер 225,000. Таким образом, вы хотите знать, какой рабочий содержит этот элемент, и в какой положение в локальной части вектора на том рабочем. globalIndices
функция обеспечивает корреляцию между локальной и глобальной индексацией codistributed массива.
D = rand(1,1e6,'distributed'); %Distributed by columns spmd globalInd = globalIndices(D,2); pos = find(globalInd == 225e3); if ~isempty(pos) fprintf(... 'Element is in position %d on worker %d.\n', pos, labindex); end end
Если при запуске этот код по пулу четырех рабочих, вы получаете этот результат:
Lab 1: Element is in position 225000 on worker 1.
Если при запуске этот код по пулу пяти рабочих, вы получаете этот результат:
Lab 2: Element is in position 25000 on worker 2.
Заметьте, используете ли вы пул различного размера, элемент заканчивается в другом месте на различном рабочем, но тот же код может использоваться, чтобы определить местоположение элемента.
Как альтернатива распределению одной размерностью строк или столбцов, можно распределить матрицу блоками с помощью '2dbc'
или двумерное циклическое блоком распределение. Вместо сегментов, которые включают много полных строк или столбцов матрицы, сегменты codistributed массива являются 2-мерными квадратными блоками.
Например, считайте простое 8 8 матрицей с возрастающими значениями элемента. Можно создать этот массив в spmd
оператор или связывающееся задание.
spmd A = reshape(1:64, 8, 8) end
Результатом является реплицированный массив:
1 9 17 25 33 41 49 57 2 10 18 26 34 42 50 58 3 11 19 27 35 43 51 59 4 12 20 28 36 44 52 60 5 13 21 29 37 45 53 61 6 14 22 30 38 46 54 62 7 15 23 31 39 47 55 63 8 16 24 32 40 48 56 64
Предположим, что вы хотите распределить этот массив среди четырех рабочих с блоком 4 на 4 как локальная часть на каждом рабочем. В этом случае сетка лаборатории является расположением 2 на 2 рабочих, и размер блока является квадратом четырех элементов на стороне (т.е. каждый блок является квадратом 4 на 4). С этой информацией можно задать объект codistributor:
spmd DIST = codistributor2dbc([2 2], 4); end
Теперь можно использовать этот объект codistributor распределить исходную матрицу:
spmd AA = codistributed(A, DIST) end
Это распределяет массив среди рабочих согласно этой схеме:
Если сетка лаборатории отлично не накладывает размерности codistributed массива, можно все еще использовать '2dbc'
распределение, которое является циклическим блоком. В этом случае можно вообразить сетку лаборатории, неоднократно накладываемую в обеих размерностях, пока все исходные элементы матрицы не включены.
Используя тот же оригинал 8 8 матричная и сетка лаборатории 2 на 2, рассмотрите размер блока 3 вместо 4, так, чтобы 3х3 квадратные блоки были распределены среди рабочих. Код выглядит так:
spmd DIST = codistributor2dbc([2 2], 3) AA = codistributed(A, DIST) end
Первая “строка” сетки лаборатории распределяется рабочему 1 и рабочему 2, но это содержит только шесть из восьми столбцов исходной матрицы. Поэтому следующие два столбца распределяются рабочему 1. Этот процесс продолжается, пока все столбцы в первых строках не распределяются. Затем подобный процесс применяется к строкам, в то время как вы продолжаете вниз матрица, как показано в следующей схеме распределения:
Схема выше показов схема, которая требует, чтобы четыре оверлейных программ сетки лаборатории разместили целую исходную матрицу. Следующий код показывает получившееся распределение данных каждому из рабочих.
spmd getLocalPart(AA) end
Lab 1: ans = 1 9 17 49 57 2 10 18 50 58 3 11 19 51 59 7 15 23 55 63 8 16 24 56 64 Lab 2: ans = 25 33 41 26 34 42 27 35 43 31 39 47 32 40 48 Lab 3: ans = 4 12 20 52 60 5 13 21 53 61 6 14 22 54 62 Lab 4: ans = 28 36 44 29 37 45 30 38 46
Следующие моменты стоит отметить:
'2dbc'
распределение не может предложить улучшение производительности, если размер блока не по крайней мере несколько дюжин. Размер блока по умолчанию равняется 64.
Сетка лаборатории должна быть максимально близко к квадрату.
Не все функции, которые улучшены, чтобы работать над '1d'
массивы codistributed работают над '2dbc'
массивы codistributed.