2013-07-23 39 views
10

Khi cố gắng chọn phương pháp lập chỉ mục để đề xuất, tôi đã cố gắng để làm hài lòng hiệu suất. Tuy nhiên, các phép đo lẫn lộn tôi rất nhiều. Tôi đã chạy nhiều lần trong các đơn đặt hàng khác nhau, nhưng các phép đo vẫn nhất quán. Dưới đây là cách tôi đã đo hiệu suất:Hiệu suất tạo chỉ mục

for N = [10000 15000 100000 150000] 
    x = round(rand(N,1)*5)-2; 
    idx1 = x~=0; 
    idx2 = abs(x)>0; 

    tic 
    for t = 1:5000 
     idx1 = x~=0; 
    end 
    toc 

    tic 
    for t = 1:5000 
     idx2 = abs(x)>0; 
    end 
    toc 
end 

Và đây là kết quả:

Elapsed time is 0.203504 seconds. 
Elapsed time is 0.230439 seconds. 

Elapsed time is 0.319840 seconds. 
Elapsed time is 0.352562 seconds. 

Elapsed time is 2.118108 seconds. % This is the strange part 
Elapsed time is 0.434818 seconds. 

Elapsed time is 0.508882 seconds. 
Elapsed time is 0.550144 seconds. 

tôi đã kiểm tra và cho các giá trị khoảng 100000 này cũng xảy ra, ngay cả ở các phép đo 50000 lạ xảy ra.

Vì vậy, câu hỏi của tôi là: Có ai khác trải nghiệm điều này trong một phạm vi nhất định hay không và điều gì gây ra điều này? (Đó có phải là lỗi không?)

+0

Vâng, tôi chắc chắn sẽ giả 'abs (x)> 0' sẽ chậm hơn vì nó thực sự đang làm 2 hoạt động, nhưng các thử nghiệm N 100000, không làm theo điều này. Lạ thật. Tuy nhiên tôi hầu như luôn luôn sử dụng 'x ~ = 0' vì nó chỉ thực hiện một thao tác. Cũng lưu ý, sự khác biệt giữa hai người không cao đối với tôi như nó dành cho bạn. Các thử nghiệm thứ ba chỉ là riêng biệt bởi 0,4 giây không 1,5 – MZimmerman6

+0

suy nghĩ duy nhất của tôi sẽ có một số phân bổ bộ nhớ lạ xảy ra trong nền rằng các thử nghiệm 100k ném ra – MZimmerman6

+0

Tôi thấy điều tương tự, nhưng không phải là quyết liệt (R2012b, OS X 10.8.4). Tôi sẽ không "giả định" rằng 'abs (x)> 0' thực hiện hai thao tác. Khi JIT được biên dịch, bit dấu có thể bị bỏ qua trong so sánh. Nó thực sự là trường hợp 'x ~ = 0' phức tạp hơn (tương đương với' x> 0 | x <0'). Một lý do có thể cho sự khác biệt giữa các kích thước có thể là [cache missing] (https://en.wikipedia.org/wiki/CPU_cache#Cache_miss), được thảo luận chi tiết [here] (http://stackoverflow.com/questions/8547778/tại sao-là-một-loop-so-nhiều-chậm-hơn-hai-vòng). – horchler

Trả lời

6

Điều này có thể do một số matlab tối ưu hóa tự động sử dụng cho cơ bản của nó Linear Algebra chương trình con.

Cũng giống như bạn, cấu hình của tôi (OSX 10.8.4, R2012a với cài đặt mặc định) mất nhiều thời gian để tính idx1 = x~=0 cho x (10e5 phần tử) hơn x (11e5 phần tử). Xem bảng bên trái của hình nơi thời gian xử lý (trục y) được đo cho kích thước vectơ khác nhau (trục x). Bạn sẽ thấy thời gian proceesing thấp hơn cho N> 103000. Trong bảng điều khiển này, tôi cũng hiển thị số lượng lõi đã hoạt động trong quá trình tính toán. Bạn sẽ thấy rằng không có sự sụt giảm cho cấu hình một lõi. Nó có nghĩa là matlab không tối ưu hóa việc thực hiện ~= khi 1 lõi hoạt động (không có sự song song có thể). Matlab cho phép một số thói quen tối ưu hóa khi hai điều kiện được đáp ứng: nhiều lõi và một vectơ có kích thước đủ.

Bảng bên phải hiển thị kết quả khi feature('accel','on'/off') được đặt thành tắt (doc). Ở đây, chỉ có một lõi hoạt động (1 lõi và 4 lõi giống hệt nhau) và do đó không thể tối ưu hóa được.

Cuối cùng, chức năng tôi sử dụng để kích hoạt/hủy kích hoạt lõi là maxNumCompThreads. Theo Loren Shure, maxNumCompThreads điều khiển cả JIT và BLAS. Vì feature('JIT','on'/'off') không đóng vai trò trong hiệu suất, BLAS là tùy chọn cuối cùng còn lại.

Tôi sẽ để lại câu cuối cùng cho Loren: "Thông điệp chính ở đây là bạn thường không cần phải sử dụng hàm này [maxNumCompThreads] ở tất cả! Tại sao? Bởi vì chúng tôi muốn làm cho MATLAB thực hiện công việc tốt nhất có thể cho bạn. "enter image description here

accel = {'on';'off'}; 
figure('Color','w'); 
N = 100000:1000:105000; 

for ind_accel = 2:-1:1 
    eval(['feature(''accel'',''' accel{ind_accel} ''')']); 
    tElapsed = zeros(4,length(N)); 
    for ind_core = 1:4 
     maxNumCompThreads(ind_core); 
     n_core = maxNumCompThreads; 
     for ii = 1:length(N) 
      fprintf('core asked: %d(true:%d) - N:%d\n',ind_core,n_core, ii); 
      x = round(rand(N(ii),1)*5)-2; 
      idx1 = x~=0; 
      tStart = tic; 
      for t = 1:5000 
       idx1 = x~=0; 
      end 
      tElapsed(ind_core,ii) = toc(tStart); 
     end 
    end 
    h2 = subplot(1,2,ind_accel); 
    plot(N, tElapsed,'-o','MarkerSize',10); 
    legend({('1':'4')'}); 
    xlabel('Vector size','FontSize',14); 
    ylabel('Processing time','FontSize',14); 
    set(gca,'FontSize',14,'YLim',[0.2 0.7]); 
    title(['accel ' accel{ind_accel}]); 
end 
+0

Tôi đoán rằng tối ưu hóa lý tưởng sẽ khởi động ngay khi nó dẫn đến kết quả tốt hơn. Vì vậy, nếu tôi hiểu chính xác: cho hoạt động này (trên máy tính của chúng tôi) tối ưu hóa chỉ đơn giản là đá vào quá muộn? –

+0

yep - bạn đã tìm thấy một trong các cài đặt/giới hạn "công việc tốt nhất cho bạn". Nhưng chắc chắn dev của MATLAB đã nhận thức được điều này và đã cố tình làm điều đó. – marsei

7

Tôi nghĩ rằng đây là điều cần làm với JIT (kết quả dưới đây đang sử dụng 2011b). Tùy thuộc vào hệ thống, phiên bản của Matlab, kích thước của các biến, và chính xác những gì trong vòng lặp (s), nó không phải là luôn luôn nhanh hơn để sử dụng JIT. Điều này liên quan đến hiệu ứng "khởi động", đôi khi nếu bạn chạy một tệp m nhiều lần trong một phiên, nó sẽ nhanh hơn sau lần chạy đầu tiên, vì máy gia tốc chỉ phải biên dịch một số phần của mã một lần.

JIT trên (tính năng Accel trên)

Elapsed time is 0.176765 seconds. 
Elapsed time is 0.185301 seconds. 

Elapsed time is 0.252631 seconds. 
Elapsed time is 0.284415 seconds. 

Elapsed time is 1.782446 seconds. 
Elapsed time is 0.693508 seconds. 

Elapsed time is 0.855005 seconds. 
Elapsed time is 1.004955 seconds. 

JIT tắt (Tính năng Accel tắt)

Elapsed time is 0.143924 seconds. 
Elapsed time is 0.184360 seconds. 

Elapsed time is 0.206405 seconds. 
Elapsed time is 0.306424 seconds. 

Elapsed time is 1.416654 seconds. 
Elapsed time is 2.718846 seconds. 

Elapsed time is 2.110420 seconds. 
Elapsed time is 4.027782 seconds. 

ETA, thật là thú vị để xem những gì sẽ xảy ra nếu bạn sử dụng số nguyên thay vì đôi:

JIT trên cùng một mã nhưng đã chuyển đổi x bằng cách sử dụng int8

Elapsed time is 0.202201 seconds. 
Elapsed time is 0.192103 seconds. 

Elapsed time is 0.294974 seconds. 
Elapsed time is 0.296191 seconds. 

Elapsed time is 2.001245 seconds. 
Elapsed time is 2.038713 seconds. 

Elapsed time is 0.870500 seconds. 
Elapsed time is 0.898301 seconds. 

JIT tắt, sử dụng int8

Elapsed time is 0.198611 seconds. 
Elapsed time is 0.187589 seconds. 

Elapsed time is 0.282775 seconds. 
Elapsed time is 0.282938 seconds. 

Elapsed time is 1.837561 seconds. 
Elapsed time is 1.846766 seconds. 

Elapsed time is 2.746034 seconds. 
Elapsed time is 2.760067 seconds. 
+0

Thú vị khi thấy rằng việc tắt JIT thực sự làm cho nó nhanh hơn. Tuy nhiên, nếu sự nóng lên sẽ là vấn đề, điều này sẽ không giải thích tại sao 100000 là chậm hơn 150000. Lưu ý rằng nó cũng sẽ xảy ra nếu bạn thay đổi thứ tự 'N = [10000 15000 150000 100000]' –

+0

Tôi không nghĩ rằng trên dòng lệnh. Tôi về cơ bản đoán rằng có một số chi phí để sử dụng JIT mà có thể là một chức năng của kích thước biến, và một số lợi ích mà cũng là một chức năng của kích thước biến. Lợi ích cuối cùng là lớn hơn chi phí, nhưng không cho đến khi kích thước của x> 150000 hoặc hơn (trong trường hợp này). – nkjt

+0

Nó có thể không đến từ JIT thực sự - xin vui lòng xem câu trả lời của tôi. – marsei

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