1

나는 100 개의 램프를 가지고 있습니다. 그들은 깜박입니다. 나는 그들을 얼마 동안 관찰한다. 각 램프에 대해 깜박이는 간격의 평균, 표준 및 자기 상관을 계산합니다. 이제 관찰 된 데이터를 재 샘플링하고 모든 매개 변수 (평균, 표준 편차, 자기 상관)가 일정 범위 내에있는 순열을 유지해야합니다. 내가 가진 코드는 훌륭하게 작동합니다. 그러나 매 실험마다 오랜 시간 (주) 걸립니다. 나는 12 코어와 2 테슬라 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. 절약 단계가 병목 현상이 아닙니다. 최상의 경우 10 ~ 30 분에 한 번 발생합니다.

+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^9 이상의 순열이 필요합니다. – zlon

+1

질문에 해당 정보가 없습니다. 귀하가 제공 한 정보에 대해서만 정보를 제공 할 수 있습니다. 10^9 순열의 경우 - 조금씩 성능을 향상 시키면 10^9 배가됩니다. – matlabgui