在Matlab中实现USRP的并行控制
USRPs parallel control in Matlab
我要感谢前面的每一个人阅读本文。我有一个非常具体的问题。我需要从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个工作程序(核心(,它会在第一个"步骤"函数上给我错误权限,因为多个工作程序试图执行同一个函数,因此会导致冲突。步骤是访问通用软件无线电外围设备(USRP(的Matlab例程。但当一个核心已经用某个USRP的参数执行该命令时,USRP正忙,而该命令的其他调用会导致错误,这就有点复杂了。不幸的是,并行循环没有为每个核心分配单独的"步骤"命令的调度。我的问题是,如果有任何问题,如何并行化至少三个步骤的命令,以防止核心冲突?如果只有这三步命令,其余的都可以串行完成,那也没关系。在最坏的情况下,可以通过调用三个matlab实例来完成,其中每个实例控制一个USRP,并且在步骤之前,命令可以是一些外部例程(例如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库来并行运行这些命令,但我没有这方面的经验,我不是那么熟练的程序员。viz[http://bisqwit.iki.fi/story/howto/openmp/#Sections][2]
很抱歉有一个稍大的文件,但我想向你展示我的解决方案(不完全是我的(,因为它对任何阅读过这篇文章并且更熟练的人都有帮助。我将感谢任何形式的帮助或建议。祝大家今天愉快。
对于这类问题,我建议使用SPMD而不是PARFOR。在SPMD中,您可以使用labBarrier
来同步工人。
- 控制允许动态运行c++的并发操作数
- 从控制台中删除最后打印的元素
- C++17中的并行执行策略
- 是否可以使用if constexpr删除控制流语句
- 并行用于C++17中数组索引范围内的循环
- 无法在windows控制台中为C++程序提供必要的输入
- 如何在Elixir中调用递归函数并行
- OpenMP:并行更新数组总是需要减少数组吗
- 如何使用OpenMP并行这两个循环
- 如何使用OpenMP并行化此矩阵时间矢量运算
- 如何使用OpenMP使这个循环并行
- 遍历并行数组以确定C++中的最大数字
- 控制到达非空函数clang(-Wreturn-type)的末尾
- 为什么 openmp 的并行不适用于矢量化色彩空间转换?
- 如何在 Mac 上使用 c++17 并行标准库算法?
- 控制与标准::异步的并行度
- HPX 是否提供具有粒度控制的基于任务的并行化迭代函数?
- 通过 EDSDK 并行控制佳能相机
- Visual c++并行端口控制
- 在Matlab中实现USRP的并行控制