Параллельное управление USRP в Matlab

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

'frameLength=180;
%transmit
R=zeros(frameLength,8000);
i = 1;j = 1;k=1;nStop = 8000;
while(j
<p> У этого решения есть одна проблема: он не полностью синхронизирован, потому что функции шагов выполняются серийно, поэтому небольшая задержка между сигналами от Tx1 a Tx2 на приемнике. Если я попробую это с помощью parfor, предположим, что matlabpool вызывает 4 рабочих (ядра), он дает мне ошибку прямо на первой "шаговой" функции, потому что несколько работников пытаются выполнить одну и ту же функцию, и поэтому она вызывает столкновение. Шаг - это процедура Matlab для доступа к универсальному программному радио периферийному устройству (USRP). Но его немного сложнее, когда одно ядро уже выполняет эту команду с аргументом некоторого USRP, что USRP занят, а другой вызов этой команды вызывает ошибку. К сожалению, нет никакого планирования для параллельных циклов, чтобы назначать индивидуальные "шаговые" команды для каждого ядра. Мой вопрос в том, есть ли какой-либо вопрос, как распараллелить как минимум три шага команды с предотвращением столкновения ядер? Если только эти три шага команды, остальное можно сделать серийным путем, это не имеет значения. Это можно сделать в худшем случае, вызвав три экземпляра matlab, где каждый экземпляр управляет одним USRP, и до того, как команда step может быть какой-то внешней процедурой (например, бит-бит в C, например), чтобы синхронизировать эти задачи.</p> <p> Ive уже попытался использовать эту процедуру семафора, чтобы создать барьер для каждого ядра, чтобы остановить и подождать до шаговых команд. <a href="http://bisqwit.iki.fi/story/howto/openmp/#Sections%23Sections" rel="nofollow noreferrer" target="_blank">http://www.mathworks.com/matlabcentral/fileexchange/45504-semaphore-posix-and-windows</a> Этот пример показан здесь:</p> <pre class="prettyprint linenums">function init() (1) exitThreads = false; % used to exit func1, func2, func3 threads. (2)cntMutexKey = 5; % mutex for doneCnt. (3)doneCnt = 0; % func1-3 increment this when they finish. (4)barrierCnt = 0; %global (5)barrierKey = 7; %global (6)paralellTasksDoneKey = 8; %global, semaphore to tell main loop when func1-3 are done. (7)semaphore('create', cntMutexKey, 1); (8)semaphore('create', barrierKey, 4); %Has count of 3 for each of the three functions to execute in parallel. We want to initialize it to 0. (9)semaphore('wait', barrierKey); %now it has 3 (10)semaphore('wait', barrierKey); %now it has 2 (11)semaphore('wait', barrierKey); %now it has 1 (12)semaphore('wait', barrierKey); %now it has 0 (13)semaphore('create', paralellTasksDoneKey, 1); (14)semaphore('wait', paralellTasksDoneKey); %Set it to 0. (15)funList = {@func1,@func2,@func3}; (16)matlabpool (17)parfor i=1:length(funList) %Start 3 threads. funList{i}(); (18)end (jump to) mycycle(); %Now run your code. exitThreads = true; %Tell func1-3 to exit. end global exitThreads while(~exitThreads) barrier(); step(hTx1,data1(:,l)); done(); end end function func2() global exitThreads while(~exitThreads) barrier(); step(hTx2,data2(:,l)); done(); end end function func3() global exitThreads Y LEN while(~exitThreads) barrier(); [Y, LEN]=step(hRx); %need [Y,LEN] global or something, and run "parfor j=1:8000" sequentially and not in paralell. done(); end end (25)function barrier() (26)semaphore('wait', cntMutexKey); %init to 1, after 3 cores increment to 4 it proceed IF (27)barrierCnt = barrierCnt+1; %changed from barrierCnt += 1 (28)if(barrierCnt == 4) %We now know that func1,func2,func3,yourcode are all at the barrier. (29)barrierCnt = 0; %reset count (30)semaphore('post', cntMutexKey); (31)semaphore('post', barrierKey); %Increment barrier count, so a func will run. (32)semaphore('post', barrierKey); %Increment barrier count, so a func will run. (33)semaphore('post', barrierKey); %Increment barrier count, so a func will run. else (34)semaphore('post', cntMutexKey); (get stuck here)semaphore('wait', barrierKey); %Wait for other threads (the barrier). end end function done() semaphore('wait', doneKey); doneCnt = doneCnt+ 1; %changed from doneCnt += 1 if(doneCnt == 3) semaphore('post', paralellTasksDoneKey); doneCnt = 0; %Reset counter. end semaphore('post', doneKey); end function mycycle() (19) global paralellTasksDoneKey Y LEN data (21)for j=1:8000 % three times send and recieved frame with nPackets, (22)i=1; %example is done with this loop handled sequentially. (23)l=1; % More complex to allow this in paralell, but its not necessary (24)k=1; (jump to) barrier(); %Want loop to stop here &amp; allow func1,func2,func3 do to their work. semaphore('wait', paralellTasksDoneKey); %Wait for func1,func2,func3 to finish. data=Y; if mod(i,nPacket)==0 %end of frame i = 0; end if LEN==frameLength R(:,k)=data; k=k+1; end i = i+1; l=l+1; end end</pre> <p> * Примечание: числа и прыжки в скобках указывают поток программы, шаг за шагом от debbuger. Заключительная программа застряла там (35). Или это можно сделать, используя библиотеку OpenMP в C, чтобы запускать эти команды параллельно, но я не испытываю этого, я не настолько опытный программист. viz [ <a href="http://bisqwit.iki.fi/story/howto/openmp/#Sections%5D%5B2%5D%23Sections%5D%5B2%5D" rel="nofollow noreferrer" target="_blank">http://bisqwit.iki.fi/story/howto/openmp/#Sections][2]</a></p> <p> Извините за немного более крупный файл, но я хочу показать вам свои решения (не полностью мои), потому что это может быть полезно для тех, кто читает это и является более опытным. Я буду благодарен за любую помощь или совет. Имейте приятный день для всех вас.</p>
1 ответ

Я бы предложил использовать SPMD, а не PARFOR для такого рода проблем. Внутри SPMD вы можете использовать labBarrier для синхронизации рабочих.

licensed under cc by-sa 3.0 with attribution.