2016-06-07 71 views
2

我需要並行化代碼以節省時間。我有一個內部到另一個循環的循環,我想並行化外部循環(因爲我認爲這樣代碼更快)。我的代碼如下所示:在外部使用parfor的雙循環錯誤

A = rand(1000,1); 
B = rand(1000,1); 
Biggers = zeros(1000,1000); 
parfor i = 1:size(A,1) 
    for j= 1:1:size(B,1) 
     if B(i,1) > A(j,1) 
      Biggers(i,j) = A(j,1); 
     end 
    end 
end 

,但如果我運行它這樣,我得到的錯誤:

Error: The variable Biggers in a parfor cannot be classified. 
See Parallel for Loops in MATLAB, "Overview". 

,如果我不是並行的內部循環,也就是說,如果設計的代碼這種情況不會發生如:

A = rand(1000,1); 
B = rand(1000,1); 
Biggers = zeros(1000,1000); 
for i = 1:size(A,1) 
    parfor j= 1:1:size(B,1) 
     if B(i,1) > A(j,1) 
      Biggers(i,j) = A(j,1); 
     end 
    end 
end 

我不明白,爲什麼在第一種情況下Biggers不被視爲一個切片變量,因爲每個工人只專注於我行變量。

我該如何解決問題?

回答

3

至於爲什麼它不能與外部循環一起工作,我不確定。 MATLAB對什麼可以和什麼不能進入parfor循環有非常嚴格的規定,這些循環並不總是很清晰。

「簡單」的解決辦法是換一切,你有parfor環路成一個函數,然後parfor突然什麼都吃。即

function Biggers = parforfunc(A,B,ii) 
for jj= 1:size(B,1) 
    if B(ii,1) > A(jj,1) 
     Biggers(ii,jj) = A(jj,1); 
    end 
end 
end 

保存,作爲parforfunc.m並運行

A = rand(1000,1); 
B = rand(1000,1); 
Biggers = zeros(size(B,1),size(A,1)); 
parfor ii = 1:size(A,1) 
    Biggers = parforfunc(A,B,ii); 
end 
3

@阿德里安的回答巧妙地解決了這個問題你的腳本 - 但如果你好奇,這裏的問題是「非恆定」界的內部for循環。您和我可以清楚地看到內部循環的界限在實踐中是不變的,但是MATLAB的規則parfor要求任何內部循環的界限都是「廣播」變量。所以,解決辦法很繁瑣 - 提升機內循環邊界計算出來的parfor循環,就像這樣:

A = rand(1000,1); 
B = rand(1000,1); 
Biggers = zeros(1000,1000); 
n = size(B,1); 
parfor i = 1:size(A,1) 
    for j= 1:n 
     if B(i,1) > A(j,1) 
      Biggers(i,j) = A(j,1); 
     end 
    end 
end 

這種情況說明in the doc