我要感谢前面的每个人读到这篇文章。我有一个非常具体的问题。我需要从Matlab中同时控制三个USRP。这是我的系列解决方案:

`frameLength=180;
%transmit
R=zeros(frameLength,8000);
i = 1;j = 1;k=1;nStop = 8000;
while(j<nStop)  % three times of lenght of frame
step(hTx1,data1(:,i)); % Tx1 transmit data in interval i
step(hTx2,data2(:,i)); %Tx2 transmit data in interval i
[Y, LEN]=step(hRx);  %receiver recieve data from Tx1 and Tx2 (but shifted)
data=Y; %just reorganzied
if mod(i,nPacket)==0 % end of column (packet, start new packet)
    i = 0;
end
if LEN==frameLength %just reorganizing
    R(:,k)=data;
    k=k+1
    if k == nStop
        break; %end
    end
end
i = i+1;
j = j+1
end`

这个解决方案有一个问题,它没有完全同步,因为步进函数是串行执行的,因此来自接收机上Tx1和Tx2的信号之间的延迟很小。
如果我用parfor尝试这个方法,让我们假设matlabpool调用4个workers(cores),它会在第一个“step”函数上给我一个错误权限,因为多个workers试图执行同一个函数,因此会导致冲突。步骤是用Matlab例程访问通用软件无线电外设(USRP)。但是当一个内核已经用某个USRP的参数执行了这个命令,USRP很忙,而这个命令的另一个调用导致了错误时,这个问题就有点复杂了。
不幸的是,并行循环没有为每个核心分配单独的“step”命令的调度。
我的问题是,如果有任何问题,如何并行至少三个步骤的命令与防止核心冲突?如果只有这三个步骤的命令,其余的可以做串行方式,这并不重要。
在最坏的情况下,可以通过调用三个matlab实例来完成,其中每个实例控制一个USRP,在step命令之前,可以使用一些外部例程(例如C中的x位计数器)来同步这些任务。
我已经尝试过使用这个信号量例程来为每个核心创建障碍,以便在step命令之前停止并等待。http://www.mathworks.com/matlabcentral/fileexchange/45504-semaphore-posix-and-windows
此示例如下所示:
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 & 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

*注:括号中的数字和跳跃表示程序的流程,一步一步地从debbuger开始。结束程序卡在那里(35)。
或者可以通过使用C语言中的OpenMP库并行运行这些命令来完成,但我没有这方面的经验,我不是很熟练的程序员。即[http://bisqwit.iki.fi/story/howto/openmp/#Sections][2]
很抱歉文件有点大,但我想向您展示我的解决方案(不完全是我的),因为它可以帮助任何人谁读这个,更熟练。我将感谢任何帮助或建议。祝大家今天愉快。

最佳答案

对于这种问题,我建议使用SPMD而不是原谅。在SPMD中,您可以使用labBarrier来同步工人。

关于c++ - Matlab中的USRP并行控制,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23395910/

10-12 16:13