2012-05-10 30 views
5

đang vector hóa trong Matlab chạy nhanh hơn nhiều so với một vòng lặp for (xem Parallel computing in Octave on a single machine -- package and example cho kết quả cụ thể trong Octave)bản vẽ Gia cho meshgrid trong Matlab (hoặc Octave)

Với những gì đã nói, là có một cách để vectorize mã hiển thị bên cạnh trong Matlab hoặc Octave?

x = -2:0.01:2; 
y = -2:0.01:2; 
[xx,yy] = meshgrid(x,y); 
z = sin(xx.^2-yy.^2); 
+0

Kiểm tra việc triển khai 'bsxfun' vừa được thêm vào, mà cũng nói về việc sử dụng GPU [ở đây] (http://stackoverflow.com/a/25162350/3293881) – Divakar

Trả lời

6

Như đã chỉ ra bởi @Jonas, có một vài tùy chọn có sẵn trong MATLAB, và đó hoạt động tốt nhất phụ thuộc vào một vài yếu tố như:

  • Làm thế nào lớn là vấn đề của bạn
  • Có bao nhiêu máy bạn có sẵn
  • bạn có một GPU
  • Liệu MATLAB đã multithread các hoạt động

Nhiều el các hoạt động ementwise được đa luồng trong MATLAB ngay bây giờ - trong trường hợp này, thường có ít điểm sử dụng PARFOR (trừ khi bạn có nhiều máy và có sẵn các giấy phép Máy chủ Phân tán MATLAB).

Các vấn đề thực sự lớn cần bộ nhớ của nhiều máy có thể được hưởng lợi từ distributed arrays.

Sử dụng GPU có thể đánh bại hiệu suất đa luồng của một máy nếu vấn đề của bạn có kích thước và loại phù hợp để tính toán GPU. Mã vectơ có xu hướng là sự phù hợp tự nhiên nhất để song song thông qua GPU. Ví dụ, bạn có thể viết mã của bạn bằng cách sử dụng gpuArray s từ Hộp công cụ tính toán song song như vậy và có mọi thứ chạy trên GPU.

x = parallel.gpu.GPUArray.colon(-2,0.01,2); 
y = x; 
[xx,yy] = meshgrid(x,y); % xx and yy are on the GPU 
z = arrayfun(@(u, v) sin(u.*u-v.*v), xx, yy); 

tôi chuyển đổi dòng cuối cùng đó vào một cuộc gọi arrayfun như đó là hiệu quả hơn khi sử dụng gpuArray s.

+0

Tuyệt vời! Bạn đang ở ngay trong đó Matlab tự động đa luồng tính toán tôi đã đưa ra ở trên. Tôi đã chạy tính toán từ nhà mà không có Hộp công cụ tính toán song song, và bây giờ tôi đã chạy nó trên một máy tính với hộp công cụ và nó đã được thực hiện song song. Và cảm ơn ví dụ về GPU ... Tôi chưa bao giờ sử dụng GPU, nhưng tôi nghi ngờ một trong số đó sẽ có ích trong tương lai và rất tốt để biết mã có vẻ đơn giản – db1234

+0

Mặc dù, một bài đăng cũ, tôi đã có thể để triển khai nó với bsxfun trên GPU và tăng tốc tốt. Đăng một giải pháp ở đây trên cùng! – Divakar

5

Trong Matlab, cách duy nhất để tích hợp chức năng vectơ thành đa luồng là đợi MathWorks implement them như vậy.

Hoặc, bạn có thể viết phép tính vectơ làm vòng lặp và chạy chúng song song bằng cách sử dụng parfor.

Cuối cùng, một số chức năng là GPU-enabled, do đó, với quyền truy cập vào hộp công cụ xử lý song song, bạn có thể song song các hoạt động này, bao gồm phép trừ và quyền lực thành phần.

+0

' vòng lặp for trong Matlab có xu hướng chậm hơn so với vectorized tính toán. Vì vậy, tình hình lý tưởng cho hiệu suất tối ưu có vẻ là để thử và song song mã vectơ, nếu có thể. – db1234

+1

@dblazevski: 'parfor' giúp, nhưng bạn có thể muốn xem xét một số mã trên GPU. Xem chỉnh sửa của tôi. Ngoài ra, trong các phiên bản gần đây của Matlab, các vòng lặp 'for' đã trở nên cực kỳ nhanh. – Jonas

+0

Đúng. Tôi đã thử nghiệm ví dụ được đưa ra trong http://stackoverflow.com/questions/10520495/parallel-computing-in-octave-on-a-single-machine-package-and-example/10543033#10543033 Tôi thậm chí đã tinh chỉnh lưới nhiều. Trong Matlab, vòng lặp 'for' chậm hơn, nhưng chỉ khoảng 5 lần so với phiên bản vectơ. Trong Octave, mã vòng lặp 'for' mất * nhiều * dài hơn (như dài hơn 100 lần ...). Tôi đã tò mò về GPU trong một thời gian, mặc dù đã không cho họ một thử ... bạn có biết một điểm khởi đầu để tìm hiểu để sử dụng/chương trình một GPU? – db1234

5

bản vẽ Gia cho meshgridndgrid

Nếu bạn vẫn còn quan tâm đến việc tìm kiếm một việc thực hiện vectorized để làm cho meshgrid dựa mã trong vấn đề nhanh hơn, hãy để tôi đề nghị một phương pháp vectorized với bsxfun và đó là GPU chuyển phiên bản. Tôi thực sự tin rằng mọi người phải xem xét vectorization with GPUs như một tùy chọn đầy hứa hẹn để tăng tốc độ MATLAB mã. Mã sử ​​dụng meshgrid hoặc ndgrid và kết quả đầu ra của chúng sẽ được vận hành với một số thiết lập hoạt động theo nguyên tố, một nền tảng hoàn hảo để sử dụng bsxfun vào các mã đó. Để thêm vào đó, việc sử dụng GPU với bsxfun, cho phép nó hoạt động độc lập với hàng trăm và hàng nghìn lõi CUDA, làm cho nó hoàn hảo cho việc triển khai GPU.

Đối với vấn đề cụ thể của bạn, đầu vào là -

x = -2:0.01:2; 
y = -2:0.01:2; 

Tiếp theo, bạn có -

[xx,yy] = meshgrid(x,y); 
z = sin(xx.^2-yy.^2); 

Với bsxfun, điều này trở thành một lớp lót -

z = sin(bsxfun(@minus,x.^2,y.^2.')); 

Điểm chuẩn

Mẹo đo điểm chuẩn GPU được lấy từ Measure and Improve GPU Performance.

%// Warm up GPU call with insignificant small scalar inputs 
temp1 = sin_sqdiff_vect2(0,0); 

N_arr = [50 100 200 500 1000 2000 3000]; %// array elements for N (datasize) 
timeall = zeros(3,numel(N_arr)); 

for k = 1:numel(N_arr) 
    N = N_arr(k); 
    x = linspace(-20,20,N); 
    y = linspace(-20,20,N); 

    f = @() sin_sqdiff_org(x,y);%// Original CPU code 
    timeall(1,k) = timeit(f); 
    clear f 

    f = @() sin_sqdiff_vect1(x,y);%// Vectorized CPU code 
    timeall(2,k) = timeit(f); 
    clear f 

    f = @() sin_sqdiff_vect2(x,y);%// Vectorized GPU(GTX 750Ti) code 
    timeall(3,k) = gputimeit(f); 
    clear f 
end 

%// Display benchmark results 
figure,hold on, grid on 
plot(N_arr,timeall(1,:),'-b.') 
plot(N_arr,timeall(2,:),'-ro') 
plot(N_arr,timeall(3,:),'-kx') 
legend('Original CPU','Vectorized CPU','Vectorized GPU (GTX 750 Ti)') 
xlabel('Datasize (N) ->'),ylabel('Time(sec) ->') 

Associated chức năng

%// Original code 
function z = sin_sqdiff_org(x,y) 
[xx,yy] = meshgrid(x,y); 
z = sin(xx.^2-yy.^2); 
return; 

%// Vectorized CPU code 
function z = sin_sqdiff_vect1(x,y) 
z = sin(bsxfun(@minus,x.^2,y.^2.')); %//' 
return; 

%// Vectorized GPU code 
function z = sin_sqdiff_vect2(x,y) 
gx = gpuArray(x); 
gy = gpuArray(y); 
gz = sin(bsxfun(@minus,gx.^2,gy.^2.')); %//' 
z = gather(gz); 
return; 

Kết quả

enter image description here

Kết luận

Như kết quả cho thấy, phương pháp vectorized với GPU cho thấy imp hiệu suất tốt rovement là khoảng 4.3x so với mã CPU được vectorized và 6x so với mã gốc. Hãy ghi nhớ rằng GPU phải vượt qua một chi phí tối thiểu cần thiết với thiết lập của nó, vì vậy ít nhất một đầu vào có kích thước phù hợp là cần thiết để xem cải tiến. Hy vọng rằng, mọi người sẽ khám phá nhiều hơn vectorization with GPUs, vì nó không thể được nhấn mạnh đủ!

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