2013-05-21 23 views
5

Tôi gặp sự cố khi sử dụng các mảng cấu trúc trong vòng lặp parfor của Matlab. Các mã sau đây có 2 vấn đề tôi không hiểu:Sử dụng các mảng cấu trúc trong parfor

s=struct('a',{},'b',{}); 
if matlabpool('size')==0 
    matlabpool open local 2 
end 

for j = 1:2  
    parfor k=1:4 
    fprintf('[%d,%d]\n',k,j) 
    s(j,k).a = k; 
    s(j,k).b = j; 
    end 
end 
matlabpool close 
  1. Nó không thành công với một lỗi Error using parallel_function (line 589) Insufficient number of outputs from right hand side of equal sign to satisfy assignment.
  2. Mở đầu ra, biến s là một vector, không phải là một mảng (như nó phải được, ngay cả khi ngắt mã trước khi kết thúc).

EDIT vấn đề được giải quyết nếu tôi khởi tạo các mảng struct để kích thước chính xác, bởi:

s=struct('a',cell(2,4),'b',cell(2,4)); 

Tuy nhiên, tôi vẫn sẽ rất vui khi có được những hiểu biết về vấn đề này (ví dụ như là nó tập hợp một lỗi, theo gợi ý của Oleg Komarov)

+0

Đối với điểm 2, điều gì làm bạn có nghĩa là "mảng" hơn là "vector"? Trong Matlab không có sự phân biệt. Có vẻ như tôi 's' nên là một ma trận 2x4 của' struct 'ở cuối mã này. – jazzbassrob

+0

Tôi nghĩ rằng nó thực sự là một lỗi và tôi khuyên bạn nên gửi một [hỗ trợ equest] (http://www.mathworks.it/support/service_requests/contact_support.do?) Và giữ cho chúng tôi cập nhật. – Oleg

+0

@jazzbassrob, một vectơ là một mảng 1xd (hoặc dx1). –

Trả lời

3

Ban đầu nó hoạt động tốt cho tôi nhưng sau đó tôi không biết điều gì xảy ra. Nói chung, bạn cần phải cẩn thận với các vòng parfor và có tài liệu phong phú về cách sắp xếp mọi thứ. Hai lời khuyên khác nhau. Đầu tiên và quan trọng hơn, các vòng lặp parfor là trên vòng lặp bên ngoài:

function s = foo 
s=struct('a',{},'b',{}); 

parfor j = 1:2  
    for k=1:4 
    fprintf('[%d,%d]\n',k,j) 
    s(j,k).a = k; 
    s(j,k).b = j; 
    end 
end 

Hai, Matlab được rất kén chọn về cách viết biến lối chính (tức là biến chứa trong vòng parfor được lập chỉ mục cho các vòng lặp, trong trường hợp của bạn, s). Trước tiên, bạn muốn tạo một biến giả chứa tất cả các thông tin bên trong, và sau đó ghi vào nó một lần ở cuối các vòng lặp. Ví dụ:

function s = khal 
s=struct('a',{},'b',{}); 


parfor j = 1:2 
    dummy=struct('a',{},'b',{}); 
    for k=1:4 
    fprintf('[%d,%d]\n',k,j) 
    dummy(k).a = k; 
    dummy(k).b = j; 
    end 
    s(j,:) = dummy; 
end 

Bạn không cần phải là một vấn đề ở đây, nhưng nó có thể trở nên phức tạp trong các trường hợp khác

+0

Tại sao parfor nên ở vòng ngoài? Nếu tôi có vòng lặp ngoài trên chỉ mục [1,2] và vòng lặp bên trong trên chỉ mục [1, ..., 1000], vòng lặp bên trong dài hơn sẽ không được song song, phải không? –

+0

có một chi phí đầu tư để có các vòng parfor, và có những trường hợp sẽ có hiệu quả về chi phí trong vòng lặp bên trong (đặc biệt nếu bạn có nhiều hơn hai hồ bơi chạy), nhưng nói chung, bạn nên cấu trúc mã vòng lặp parfor nằm trong vòng lặp ngoài. Với một hồ bơi 2, nó sẽ hầu như luôn luôn nhanh hơn với parfor trong vòng ngoài (thử và so sánh ...). – Rasman

+0

Câu trả lời hay! Bằng cách nào đó nếu bạn chỉ mục cấu trúc ban đầu với biến cắt của 'vòng lặp parfor' (trong trường hợp này là' j'), nó hoạt động. Lập chỉ mục theo bất kỳ cách nào khác dường như không hoạt động. Ví dụ, 's (1, :)' không hoạt động nhưng 's (j, :)' làm! –

Các vấn đề liên quan