1

私は100個のランプを持っています。彼らは点滅している。私はそれらをある時間の間観察する。各ランプについて、平均、標準偏差および点滅間隔の自己相関を計算する。 ここでは、観測データを再サンプリングし、すべてのパラメータ(平均、標準偏差、自己相関)がある範囲内にある順列を保つ必要があります。私が働いているコードは良いです。しかし、それは実験の各ラウンドに長い時間(週)かかる。私は12のコアと2つのTesla K40m GPUを搭載したコンピューティングサーバ上で行います(詳細は最後にあります)。シャッフルの速度が制限されています。 GPU(Tesla K40m)、MATLABのCPU並列計算

マイコード:

close all 
clear all 
clc 
% open parpool skip error if it was opened 
try parpool(24); end 

% Sample input. It is faked, just for demo. 
% Number of "lamps" and number of "blinks" are similar to real. 
NLamps = 10^2; 
NBlinks = 2*10^2; 
Events = cumsum([randg(9,NLamps,NBlinks)],2); % each row - different "lamp" 
DurationOfExperiment=Events(:,end).*1.01; 

%% MAIN 
% Define parameters 
nLags=2; % I need to keep autocorrelation with lags 1-2 
alpha=[0.01,0.1]; % range of allowed relative deviation from observed 
        % parameters should be > 0 to avoid generating original 
        % sequence 
nPermutations=10^2; % In original code 10^5     

% Processing of experimental data     
DurationOfExperiment=num2cell(DurationOfExperiment); 
Events=num2cell(Events,2); 
Intervals=cellfun(@(x) diff(x),Events,'UniformOutput',false); 
observedParams=cellfun(@(x) fGetParameters(x,nLags),Intervals,'UniformOutput',false); 
observedParams=cell2mat(observedParams); 

% Constrained shuffling. EXPENSIVE PART!!! 
while true 
    parfor iPermutation=1:nPermutations 
     % Shuffle intervals 
     shuffledIntervals=cellfun(@(x,y) fPermute(x,y),Intervals,DurationOfExperiment,'UniformOutput',false); 
     % get parameters of shuffled intervals 
     shuffledParameters=cellfun(@(x) fGetParameters(x,nLags),shuffledIntervals,'UniformOutput',false); 
     shuffledParameters=cell2mat(shuffledParameters); 
     % get relative deviation 
     delta=abs((shuffledParameters-observedParams)./observedParams); 
     % find shuffled Lamps, which are inside alpha range 
     MaximumDeviation=max(delta,[] ,2); 
     MinimumDeviation=min(delta,[] ,2); 
     LampID=find(and(MaximumDeviation<alpha(2),MinimumDeviation>alpha(1))); 
     % if shuffling of ANY lamp was succesful, save these Intervals 
     if ~isempty(LampID) 
      shuffledIntervals=shuffledIntervals(LampID); 
      shuffledParameters=shuffledParameters(LampID,:); 
      parsave(LampID,shuffledIntervals,shuffledParameters); 
      'DONE' 
     end 
    end 
end 



%% FUNCTIONS 
function [ params ] = fGetParameters(intervals,nLags) 
% Calculate [mean,std,autocorrelations with lags from 1 to nLags 
    R=nan(1,nLags); 
    for lag=1:nLags 
      R(lag) = corr(intervals(1:end-lag)',intervals((1+lag):end)','type','Spearman'); 
    end 
    params = [mean(intervals),std(intervals),R]; 
end 
%-------------------------------------------------------------------------- 
function [ Intervals ] = fPermute(Intervals,Duration) 
    % Create long shuffled time-series 
    Time=cumsum([0,datasample(Intervals,numel(Intervals)*3)]); 
    % Keep the same duration 
    Time(Time>Duration)=[]; 
    % Calculate Intervals 
    Intervals=diff(Time); 
end 
%-------------------------------------------------------------------------- 
function parsave(LampID,Intervals,params) 
    save([num2str(randi(10^9)),'.mat'],'LampID','Intervals','params') 
end 

サーバーのスペック:

>>gpuDevice() 
CUDADevice with properties: 

         Name: 'Tesla K40m' 
        Index: 1 
     ComputeCapability: '3.5' 
      SupportsDouble: 1 
      DriverVersion: 8 
      ToolkitVersion: 8 
     MaxThreadsPerBlock: 1024 
      MaxShmemPerBlock: 49152 
     MaxThreadBlockSize: [1024 1024 64] 
       MaxGridSize: [2.1475e+09 65535 65535] 
       SIMDWidth: 32 
       TotalMemory: 1.1979e+10 
      AvailableMemory: 1.1846e+10 
     MultiprocessorCount: 15 
       ClockRateKHz: 745000 
       ComputeMode: 'Default' 
     GPUOverlapsTransfers: 1 
    KernelExecutionTimeout: 0 
      CanMapHostMemory: 1 
      DeviceSupported: 1 
      DeviceSelected: 1 
>> feature('numcores') 
MATLAB detected: 12 physical cores. 
MATLAB detected: 24 logical cores. 
MATLAB was assigned: 24 logical cores by the OS. 
MATLAB is using: 12 logical cores. 
MATLAB is not using all logical cores because hyper-threading is enabled. 

>> system('for /f "tokens=2 delims==" %A in (''wmic cpu get name /value'') do @(echo %A)') 
Intel(R) Xeon(R) CPU E5-2630 v2 @ 2.60GHz 
Intel(R) Xeon(R) CPU E5-2630 v2 @ 2.60GHz 

>> memory 
Maximum possible array:    496890 MB (5.210e+11 bytes) * 
Memory available for all arrays:  496890 MB (5.210e+11 bytes) * 
Memory used by MATLAB:     18534 MB (1.943e+10 bytes) 
Physical Memory (RAM):    262109 MB (2.748e+11 bytes) 

* Limited by System Memory (physical + swap file) available. 

質問:

それは私の計算を高速化することは可能ですか?私はCPU + GPUコンピューティングについて考えていますが、私はそれを行う方法を理解できませんでした(私はgpuArraysでの経験はありません)。さらに、私はそれが良いアイデアであるかどうかはわかりません。場合によってはアルゴリズムの最適化によって利益が増し、次に並列コンピューティングが行われることがあります。

P.S. 節約のステップはボトルネックではありません。最良の場合は10〜30分で1回発生します。

+1

は、あなたが(データセットのサブに)あなたのコードをプロファイリング持っている - >正確に(その行(複数可))を参照してくださいするには時間が取られる場合?データやプロファイラの統計情報なしで本当に役立つ方法を教えてもらうのは難しいですが、考慮すべき点の1つは、単純にループの回数がcellfunよりも速いということです(ただし時間的に大きさの順序は変わりません... ) – matlabgui

+0

私はちょうどのためにparforを置き換えるプロファイラーを使用しています。私はいくつかの点を見つけましたが、それほど重要ではありません。問題は、プロセスを並列化する方法であり、GPUを使用する可能性があります。 – zlon

答えて

1

GPUベースの処理は、一部の機能と正しいカード(正しく覚えている場合)でのみ使用できます。あなたの質問MATLABのGPU部分について

list of available functionsを持っている - あなたはGPU上で実行できること - あなたのコードの中で最も高価な部分は残念ながらリストにない機能corrです。

プロファイラは、ボトルネックを強調されていない場合 - 奇妙な何かが起こっている...だから、私は上記のコードのいくつかのテストを実行しました:

週間よりもはるかに少ないです
nPermutations = 10^0 iteration takes  ~0.13 seconds 
nPermutations = 10^1 iteration takes  ~1.3 seconds 
nPermutations = 10^3 iteration takes ~130 seconds 
nPermutations = 10^4 probably takes ~1300 seconds 
nPermutations = 10^5 probably takes ~13000 seconds 

...

私はあなたのwhileの文のうち、breakを置くことを言及しました - あなたはwhileループの外「壊す」ここで私はあなたのコードでは見ることができなかったとして - 私はあなたのために願って、このISNこと理由はないあなたの関数は永遠に実行することを....

while true 
    parfor iPermutation=1:nPermutations 
     % Shuffle intervals 
     shuffledIntervals=cellfun(@(x,y) fPermute(x,y),Intervals,DurationOfExperiment,'UniformOutput',false); 
     % get parameters of shuffled intervals 
     shuffledParameters=cellfun(@(x) fGetParameters(x,nLags),shuffledIntervals,'UniformOutput',false); 
     shuffledParameters=cell2mat(shuffledParameters); 
     % get relative deviation 
     delta=abs((shuffledParameters-observedParams)./observedParams); 
     % find shuffled Lamps, which are inside alpha range 
     MaximumDeviation=max(delta,[] ,2); 
     MinimumDeviation=min(delta,[] ,2); 
     LampID=find(and(MaximumDeviation<alpha(2),MinimumDeviation>alpha(1))); 
     % if shuffling of ANY lamp was succesful, save these Intervals 
     if ~isempty(LampID) 
      shuffledIntervals=shuffledIntervals(LampID); 
      shuffledParameters=shuffledParameters(LampID,:); 
      parsave(LampID,shuffledIntervals,shuffledParameters); 
      'DONE' 
     end 
    end 
    break % You need to break out of the loop at some point 
      % otherwise it would run forever.... 
end 
+0

コードを編集するよりも! 1)条件付きブレークがあります。2)サンプルデータのみを表示します。実生活では、1つのランプをシャッフルして10個以上の順列が必要です。 – zlon

+1

あなたはあなたの質問にその情報を持っていませんでした。あなたが提供したものに関する情報のみを提供することができます。 10^9のパーミュテーションについては、少しずつパフォーマンスが向上します。>あなたは10^9倍になります。 – matlabgui

関連する問題