2016-04-01 15 views
9

Tôi bị tắc nghẽn hiệu suất. Tôi đang tính toán giá trị trung bình của các mảng lớn (250 hàng & 1,3 triệu cột) và tôi làm như vậy hơn một triệu lần trong ứng dụng của mình.Mảng hiệu suất cao có nghĩa là

trường hợp thử nghiệm của tôi trong Python:

import numpy as np 
big_array = np.random.random((250, 1300000)) 
%timeit mean = big_array.mean(axis = 0) # ~400 milliseconds 

NumPy mất khoảng 400 mili giây trên máy tính của tôi, chạy trên một lõi duy nhất. Tôi đã thử một số thư viện ma trận khác trên các ngôn ngữ khác nhau (Cython, R, Julia, Torch), nhưng chỉ tìm thấy Julia để đánh bại Numpy, bằng cách lấy khoảng 250 mili giây.

Có ai có thể cung cấp bằng chứng về cải thiện đáng kể hiệu suất trong tác vụ này không? Có lẽ đây là một nhiệm vụ phù hợp với GPU?

Chỉnh sửa: Ứng dụng của tôi rõ ràng bị hạn chế về bộ nhớ và hiệu suất của nó được cải thiện đáng kể bằng cách truy cập các thành phần của một mảng lớn chỉ một lần thay vì lặp lại. (Xem bình luận bên dưới.)

+1

Tính toán này có thể nhiều hơn về truy cập bộ nhớ so với hoạt động của CPU. Tôi sẽ không mong đợi bất kỳ hệ thống cải thiện đáng kể khi numpy ở đây. Trực giác của tôi là sử dụng nhiều lõi hoặc GPU sẽ không được sử dụng nhiều. Giảm xuống float32 có thể giúp mặc dù. – MRocklin

+0

Trường hợp kiểm tra có thể quá đơn giản. Kiểu mảng của tôi thực sự là boolean, vì vậy mọi phần tử được lưu trữ như một byte với Numpy. Nghịch lý, phải mất nhiều thời gian để có được trung bình hoặc tổng hợp cho một mảng boolean hơn cho phao như ví dụ. Bất kỳ ý tưởng làm thế nào để thực hiện hoạt động trên mảng bitpacked, mà sẽ làm giảm lưu lượng bộ nhớ bằng ~ 90%? –

+0

Trong ứng dụng cụ thể của tôi, tôi lấy giá trị trung bình của các mảng là các tập con 250 hàng của một mảng 22.000 hàng. Bộ nhớ truy cập một mình đến 24 giờ cho toàn bộ tính toán. Tuy nhiên, nếu tôi hoạt động trên ma trận lớn hơn và chỉ chạm vào từng phần tử một lần, bộ nhớ sẽ truy cập tổng cộng ít hơn 10 giây. Tôi sẽ phải thử điều đó! Cảm ơn @MRocklin vì đã chỉ ra nút cổ chai. –

Trả lời

9

Julia, nếu tôi không nhầm, hãy sử dụng fortran đặt hàng trong bộ nhớ trái ngược với việc sử dụng bộ nhớ C theo mặc định. Vì vậy, nếu bạn sắp xếp lại mọi thứ phải tuân theo cùng một bố trí sao cho giá trị trung bình đang diễn ra cùng bộ nhớ kề nhau, bạn sẽ có được hiệu suất tốt hơn:

In [1]: import numpy as np 

In [2]: big_array = np.random.random((250, 1300000)) 

In [4]: big_array_f = np.asfortranarray(big_array) 

In [5]: %timeit mean = big_array.mean(axis = 0) 
1 loop, best of 3: 319 ms per loop 

In [6]: %timeit mean = big_array_f.mean(axis = 0) 
1 loop, best of 3: 205 ms per loop 

Hoặc bạn chỉ có thể thay đổi bạn kích thước và lấy giá trị trung bình so với trục khác:

In [10]: big_array = np.random.random((1300000, 250)) 

In [11]: %timeit mean = big_array.mean(axis = 1) 
1 loop, best of 3: 205 ms per loop 
+0

Trên máy tính của tôi, thời gian được đảo ngược: Trong [56]:% timeit big_array.mean (0) -> 705 ms mỗi vòng lặp; Trong [57]:% timeit big_arrayf.mean (0) -> 1201 ms mỗi vòng lặp; Bạn có ý tưởng gì không? –

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