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

Я вполне уверен, что сбой произошел не из-за невозможности предварительного выделения переменных, а из-за того, что Matlab вычисляет спектр по-другому:

Вот простой скрипт, демонстрирующий проблему (в Ubuntu и R2012b):

% allocate the data and objects
mtm = spectrum.mtm;
data = rand(3000,1);
Fs = 500;

fprintf('Entering for loop\n');
for i = 1:5
    h = psd(mtm, data, 'Fs', Fs);
end

fprintf('Entering parfor loop\n');
parfor i = 1:10
    h = psd(mtm, data, 'Fs', Fs);
end

Цикл for выполняется правильно, однако ошибки parfor отсутствуют. Вот результат:

Вход в цикл

Вход в цикл parfor

Предупреждение: PSD заменен объектами SPECTRUM. PSD все еще работает, но может быть удален в будущем. Вместо этого используйте SPECTRUM (или его функциональную форму PWELCH).

В psd, 33, параллельная_функция> make_general_channel / channel_general, 885 дюймов remoteParallelFunction at 30 Ошибка при использовании parallel_function (строка 589)

Требуется векторный ввод (строка или столбец).

Стек ошибок: psd.m на 37

Кто-нибудь сталкивался с этим раньше? Есть ли лучший способ распараллелить спектральные вычисления?

2
slayton 1 Фев 2013 в 21:25
Правильно ли работает код, если заменить parfor на for? Если это так, я предполагаю, что будущее в параллельной вселенной наступило сейчас.
 – 
Dennis Jaheruddin
1 Фев 2013 в 21:34
@DennisJaheruddin, да, вот что демонстрирует включенный код
 – 
slayton
1 Фев 2013 в 21:38
Можете ли вы просто переключиться на spectrum, как подсказывает сообщение об ошибке?
 – 
shoelzer
2 Фев 2013 в 01:13
@shoelzer, странно то, что у меня синтаксис связан с НОВЫМИ объектами спектра, но я получаю предупреждения, как будто я использую СТАРЫЙ синтаксис спектра. Обратите внимание, как я не получаю предупреждения при первом вызове psd
 – 
slayton
2 Фев 2013 в 02:03
В вашем цикле for есть состояние гонки: результат каждой итерации сохраняется в переменной h. Это создает состояние параллельной гонки, когда каждая параллельная задача пытается одновременно выполнить запись в h. Попробуйте изменить h=psd(...) на h(i)=psd(...), чтобы результат каждой итерации сохранялся в отдельном месте. Однако я подозреваю, что вы действительно хотите распараллелить вычисления внутри функции psd, так ли это?
 – 
bcumming
2 Фев 2013 в 16:09

1 ответ

Лучший ответ

После консультации со службой поддержки Mathworks проблема решена путем перемещения создания объекта spectrum.mtm внутрь цикла parfor.

Это работает

fprintf('Entering parfor loop\n');
parfor i = 1:10
    mtm = spectrum.mtm;
    h = psd(mtm, data, 'Fs', Fs);
end

Это не

mtm = spectrum.mtm;

fprintf('Entering parfor loop\n');
parfor i = 1:10
    h = psd(mtm, data, 'Fs', Fs);
end

Основная проблема заключается в том, что spectrum.mtm является объектом simulink, а не объектом Matlab, и объекты simulink не могут использоваться в циклах parfor.

1
slayton 7 Фев 2013 в 16:16