Tại sao không phải là phép nhân vectơ ma trận của tôi?


15

Xin lỗi vì bài viết dài nhưng tôi muốn bao gồm mọi thứ mà tôi nghĩ là có liên quan trong lần đầu tiên.

Những gì tôi muốn

Tôi đang triển khai một phiên bản song song của Phương pháp không gian con Krylov cho ma trận dày đặc. Chủ yếu là GMRES, QMR và CG. Tôi nhận ra (sau khi định hình) rằng thói quen DGEMV của tôi thật thảm hại. Vì vậy, tôi quyết định tập trung vào đó bằng cách cô lập nó. Tôi đã thử chạy nó trên máy 12 lõi nhưng kết quả bên dưới là dành cho máy tính xách tay Intel i3 4 lõi. Không có nhiều sự khác biệt trong xu hướng.

KMP_AFFINITY=VERBOSEĐầu ra của tôi có sẵn ở đây .

Tôi đã viết ra một mã nhỏ:

size_N = 15000
A = randomly_generated_dense_matrix(size_N,size_N); %Condition Number is not bad
b = randomly_generated_dense_vector(size_N);
for it=1:n_times %n_times I kept at 50 
 x = Matrix_Vector_Multi(A,b);
end

Tôi tin rằng điều này mô phỏng hành vi của CG trong 50 lần lặp.

Những gì tôi đã thử:

Dịch

Ban đầu tôi đã viết mã ở Fortran. Tôi đã dịch nó sang C, MATLAB và Python (Numpy). Không cần phải nói, MATLAB và Python thật kinh khủng. Đáng ngạc nhiên, C tốt hơn FORTRAN một hoặc hai giây cho các giá trị trên. Nhất quán.

Hồ sơ

Tôi lập hồ sơ mã của tôi để chạy và nó chạy trong 46.075vài giây. Đó là khi MKL_DYNAMIC được đặt thànhFALSE và tất cả các lõi đã được sử dụng. Nếu tôi sử dụng MKL_DYNAMIC là đúng, chỉ (khoảng) một nửa số lõi được sử dụng tại bất kỳ thời điểm nào. Dưới đây là một vài chi tiết:

Address Line    Assembly                CPU Time

0x5cb51c        mulpd %xmm9, %xmm14     36.591s

Quá trình tốn thời gian nhất dường như là:

Call Stack                          LAX16_N4_Loop_M16gas_1
CPU Time by Utilization             157.926s
CPU Time:Total by Utilization       94.1%
Overhead Time                       0us
Overhead Time:Total                 0.0%    
Module                              libmkl_mc3.so   

Dưới đây là một vài hình ảnh:nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

Kết luận:

Tôi là người mới bắt đầu thực sự về hồ sơ nhưng tôi nhận ra rằng tốc độ vẫn không tốt. Mã tuần tự (1 Lõi) kết thúc sau 53 giây. Đó là một tốc độ tăng ít hơn 1,1!

Câu hỏi thực tế: Tôi nên làm gì để cải thiện khả năng tăng tốc của mình?

Những thứ mà tôi nghĩ có thể giúp nhưng tôi không thể chắc chắn:

  • Thực hiện Pthreads
  • Triển khai Bộ KH & ĐT (ScaLapack)
  • Điều chỉnh thủ công (Tôi không biết làm thế nào. Vui lòng giới thiệu tài nguyên nếu bạn đề xuất điều này)

Nếu bất cứ ai cần thêm chi tiết (đặc biệt là về bộ nhớ), xin vui lòng cho tôi biết tôi nên chạy gì và làm thế nào. Tôi chưa bao giờ bộ nhớ hồ sơ trước đây.

Câu trả lời:


20

Ma trận của bạn có kích thước 15.000 x 15.000, vì vậy bạn có 225M phần tử trong ma trận. Điều này làm cho khoảng 2GB bộ nhớ. Giá trị này lớn hơn nhiều so với kích thước bộ đệm của bộ xử lý của bạn, do đó, nó phải được tải hoàn toàn từ bộ nhớ chính trong mỗi phép nhân ma trận, tạo ra khoảng 100 GB truyền dữ liệu, cộng với những gì bạn cần cho các vectơ nguồn và đích.

Dải bộ nhớ tối đa của i3 là khoảng 21 GB / giây dựa trên thông số kỹ thuật của Intel, nhưng nếu bạn nhìn quanh web, bạn sẽ thấy rằng hầu hết một nửa số đó thực sự có sẵn trong thực tế. Do đó, ít nhất, bạn mong muốn điểm chuẩn của mình kéo dài 10 giây và số đo thực tế 45 giây của bạn không nằm ngoài mốc đó.

Đồng thời, bạn cũng đang thực hiện một số phép nhân và thêm 10 tỷ dấu phẩy động. Xem xét, giả sử, 10 chu kỳ đồng hồ cho sự kết hợp và tốc độ xung nhịp 3 GHz, bạn sẽ ra mắt sau ~ 30 giây. Tất nhiên, chúng có thể chạy đồng thời với tải bộ nhớ đầu cơ nếu bộ đệm thông minh.

Nói chung, tôi muốn nói rằng bạn không quá xa vời. Bạn sẽ mong đợi điều gì?


Không có cách nào để tăng tốc tối thiểu 2-3 sao?
Thắc mắc

@Nunoxic - Bạn có thể muốn đánh giá hiệu năng bộ nhớ trên hệ thống của mình bằng một công cụ như SiSoftware Sandra. Phân tích Wolfgangs nhìn vào tôi, nếu ứng dụng của bạn bị giới hạn băng thông bộ nhớ, việc song song hóa sẽ giúp ích rất ít nếu có. Ngoài ra, hãy xem bất kỳ tùy chọn tiết kiệm năng lượng nào bạn có thể có, chúng có thể làm tăng hiệu suất bộ nhớ. Ngoài ra, hãy xem xét thay thế bộ nhớ của bạn bằng bộ nhớ chất lượng cao hơn, ví dụ độ trễ CAS thấp hơn có thể tạo ra sự khác biệt lớn cho thời gian treo tường của bạn.
Đánh dấu gian hàng

4

Làm thế nào bạn đang làm nhân ma trận-vector? Một vòng lặp đôi bằng tay? Hoặc gọi cho BLAS? Nếu bạn đang sử dụng MKL, tôi thực sự khuyên bạn nên sử dụng các thói quen BLAS của phiên bản luồng.

Vì tò mò, bạn cũng có thể muốn biên dịch phiên bản ATLAS đã điều chỉnh của riêng mình và xem điều đó giải quyết vấn đề của bạn như thế nào.

Cập nhật

Sau phần thảo luận trong các bình luận bên dưới, hóa ra Intel Core i3-330M của bạn chỉ có hai lõi "thực". Hai lõi bị thiếu được mô phỏng với siêu phân luồng . Vì trong các lõi siêu phân luồng cả bus bộ nhớ và các đơn vị dấu phẩy động được chia sẻ, bạn sẽ không nhận được bất kỳ sự tăng tốc nào nếu bất kỳ một trong hai yếu tố này là một yếu tố hạn chế. Trong thực tế, sử dụng bốn lõi thậm chí sẽ làm mọi thứ chậm lại.

Loại kết quả nào bạn nhận được trên "chỉ" hai lõi?


Tôi đã thử ATLA, GoTo và Netlib BLAS. Tất cả đều yếu hơn MKL về hiệu suất. Điều này được mong đợi hay tôi đang làm gì đó sai? Tôi đã biên soạn ATLAS như được đề cập trong cuốn cẩm nang. Hơn nữa, tôi đã dán mã (chính xác) của tôi ở đây . Nó gọi BLAS của MKL.
Thắc mắc

Ok, và để mở rộng quy mô, bạn có chắc chắn rằng trong trường hợp cơ sở của mình, mã chỉ chạy trên một CPU không? Ví dụ, nếu bạn điểm chuẩn nó, biểu đồ sử dụng CPU chỉ hiển thị một lõi đơn?
Pedro

Đúng. Biểu đồ CPU hiển thị 1 lõi.
Thắc mắc

Chỉ tò mò một lần nữa, bạn nhận được gì cho hai hoặc ba lõi? Máy của bạn thực sự có bốn lõi vật lý, hay chỉ có hai lõi với siêu phân luồng ?
Pedro

Làm thế nào để tôi tìm ra điều đó? Tôi đã bao gồm KMP_AFFINITY của tôi trong chính.
Thắc mắc

0

Tôi có ấn tượng rằng thứ tự hàng lớn là tối ưu cho vấn đề này liên quan đến thời gian truy cập bộ nhớ, sử dụng dòng bộ đệm và bỏ lỡ TLB. Tôi đoán thay thế phiên bản FORTRAN của bạn đã sử dụng thứ tự chính theo cột, điều này có thể giải thích tại sao nó luôn chậm hơn phiên bản C.

b

Bạn cũng có thể kiểm tra tốc độ nếu bạn chỉ tổng hợp tất cả các phần tử của ma trận trong một vòng lặp thay vì nhân vectơ ma trận. (Bạn có thể muốn hủy kiểm soát vòng lặp theo hệ số 4, bởi vì tính không cộng hưởng của phép cộng có thể ngăn trình biên dịch thực hiện việc tối ưu hóa này cho bạn.)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.