20% hiệu suất phạt cho một thiết kế phần mềm đẹp


17

Tôi đang viết một thư viện nhỏ để tính toán ma trận thưa thớt như một cách để dạy bản thân sử dụng tốt nhất việc lập trình hướng đối tượng. Tôi đã làm việc rất chăm chỉ để có một mô hình đối tượng đẹp, trong đó các phần (ma trận thưa thớt và các biểu đồ mô tả cấu trúc kết nối của chúng) được ghép rất lỏng lẻo. Theo quan điểm của riêng tôi, mã có thể mở rộng hơn nhiều và có thể duy trì được cho nó.

Tuy nhiên, nó cũng hơi chậm hơn so với việc tôi đã sử dụng một phương pháp thẳng thừng. Để kiểm tra sự đánh đổi của việc có mô hình đối tượng này, tôi đã viết một loại ma trận thưa thớt mới, phá vỡ sự đóng gói của biểu đồ cơ bản để xem nó sẽ chạy nhanh hơn bao nhiêu.

Lúc đầu, nó trông khá ảm đạm; mã tôi đã từng tự hào chạy chậm hơn 60% so với phiên bản không có thiết kế phần mềm thanh lịch. Nhưng, tôi đã có thể thực hiện một vài tối ưu hóa ở mức độ thấp - nội tuyến một hàm và thay đổi một vòng lặp nhỏ - mà không cần thay đổi API. Với những thay đổi đó, giờ đây chỉ chậm hơn 20% so với đối thủ.

Điều này đưa tôi đến câu hỏi của tôi: Tôi nên chấp nhận mất bao nhiêu hiệu suất nếu điều đó có nghĩa là tôi có một mô hình đối tượng đẹp?


Những hoạt động ma trận thưa thớt bạn đã đo lường?
Bill Barth

Ma trận-vector nhân lên. Các ma trận có kích thước dao động từ . Tôi đã biến chúng thành đồ thị Laplacians cho đồ thị ngẫu nhiên Erdos-Renyi với mức độ trung bình d = log 2 n . Ngoài ra, con số 20% trở nên tồi tệ hơn trên một số máy, vì vậy bây giờ tôi có xu hướng ném toàn bộ mọi thứ ra. Thở dàin= =1024,...,16384d= =đăng nhập2n
Daniel Shapero

3
Bạn đang sử dụng ngôn ngữ lập trình nào? Thông thường, một cái gì đó như C ++ sẽ cho phép bạn thoát khỏi các thiết kế (ish) thanh lịch với chi phí thấp (hoặc không tồn tại). Trong các ngôn ngữ khác không có lập trình meta (Java, Fortran, v.v.), chi phí 20% có vẻ hợp lý.
LKlevin

Bạn có thể cho chúng tôi xem mã của bạn? Bạn đã sử dụng ngôn ngữ nào? Những gì trình biên dịch và cờ biên dịch? Bạn đã tìm thấy chính xác nơi hiệu suất hit đến từ đâu? Làm thế nào bạn chắc chắn rằng bạn tìm thấy lý do đúng? Bạn đã sử dụng hồ sơ gì, và bạn đã sử dụng nó như thế nào? Bạn có chắc chắn rằng mô hình đối tượng đẹp không được triển khai không hiệu quả? 20% là đủ nhỏ để bạn cần thu thập nhiều dữ liệu và phân tích chi tiết trước khi nói chắc chắn là do thiết kế, thay vì nói, việc thực hiện kém hơn hoặc một số vấn đề mã hóa khác.
Kirill

Lưu ý phụ: tất cả mọi người dường như công khai khen ngợi thiết kế tốt trên hiệu suất thuần túy (tất nhiên với lý do rất hợp lệ). Nhưng sau đó, tại sao rất nhiều mã thế giới thực sự, thực sự không thể nhầm lẫn? Có phải tất cả các slobs mã cảm thấy tội lỗi và do đó công khai im lặng?
AlexE

Câu trả lời:


9

Rất ít nhà phát triển phần mềm khoa học hiểu các nguyên tắc tốt của thiết kế, vì vậy tôi xin lỗi nếu câu trả lời này hơi dài dòng. Từ góc độ công nghệ phần mềm, mục tiêu của nhà phát triển phần mềm khoa học là thiết kế một giải pháp thỏa mãn một tập hợp các ràng buộc thường xung đột .

Dưới đây là một số ví dụ điển hình về các ràng buộc này, như có thể được áp dụng cho thiết kế thư viện ma trận thưa thớt của bạn:

  • Hoàn thành trong một tháng
  • Chạy chính xác trên máy tính xách tay của bạn và một số máy trạm
  • Chạy hiệu quả

Các nhà khoa học đang dần chú ý hơn đến một số yêu cầu phổ biến khác từ công nghệ phần mềm:

  • Tài liệu (Hướng dẫn sử dụng, hướng dẫn, nhận xét mã)
  • Khả năng bảo trì (kiểm soát phiên bản, thử nghiệm, thiết kế mô-đun)
  • Khả năng sử dụng lại (thiết kế mô-đun, "linh hoạt")

Bạn có thể cần nhiều hơn hoặc ít hơn một trong những yêu cầu này. Nếu bạn đang cố giành giải thưởng Gordon Bell về hiệu suất, thì ngay cả phân số phần trăm cũng có liên quan và một vài thẩm phán sẽ đánh giá chất lượng mã của bạn (miễn là bạn có thể thuyết phục họ đúng). Nếu bạn đang cố gắng biện minh cho việc chạy mã này trên một tài nguyên được chia sẻ, chẳng hạn như cụm hoặc siêu máy tính, bạn thường phải bảo vệ các khiếu nại về hiệu suất của mã, nhưng những điều này hiếm khi rất nghiêm ngặt. Nếu bạn đang cố gắng xuất bản một bài báo trong một tạp chí mô tả mức tăng hiệu suất của phương pháp của bạn, thì bạn cần phải nhanh hơn so với đối thủ cạnh tranh và hiệu suất 20% là một sự đánh đổi tôi sẵn sàng thực hiện để có thể duy trì và tái sử dụng tốt hơn.

Quay trở lại câu hỏi của bạn, "thiết kế tốt", được cấp đủ thời gian phát triển, không bao giờ nên hy sinh hiệu suất. Nếu mục tiêu là tạo mã chạy nhanh nhất có thể, thì mã phải được thiết kế xung quanh các ràng buộc đó. Bạn có thể sử dụng các kỹ thuật như tạo mã, lắp ráp nội tuyến hoặc tận dụng các thư viện được điều chỉnh cao để giúp bạn giải quyết vấn đề của mình.

Nhưng nếu bạn không có đủ thời gian phát triển thì sao? Những gì đủ tốt? Vâng, nó phụ thuộc, và không ai sẽ có thể cung cấp cho bạn một câu trả lời tốt cho câu hỏi này mà không có thêm ngữ cảnh.

FWIW: Nếu bạn thực sự quan tâm đến việc viết các hạt ma trận thưa thớt hiệu năng cao, bạn nên so sánh với cài đặt PETSc được tối ưu hóa và làm việc với nhóm của họ nếu bạn đánh bại chúng, họ sẽ vui lòng kết hợp các hạt nhân được điều chỉnh vào thư viện.


Tôi tò mò về các trình tạo mã - Tôi nghĩ rằng chúng có thể hữu ích với tôi nhưng tôi lo ngại chúng sẽ khó duy trì. Tôi biết các lập trình viên Java sử dụng chúng rất nhiều nhưng họ thường được thiết kế để tạo mã cho các ứng dụng cụ thể. Bạn có biết bất kỳ mã khoa học sử dụng chúng?
Daniel Shapero

ATLAS, FFTW, Xoắn ốc, OSKI, Đánh lửa, stprint_codegen, để đặt tên cho một số. Nó không được quảng cáo công khai, nhưng tôi sẽ không ngạc nhiên nếu một số hạt nhân quan trọng trong MKL và ESSL được tạo ra theo cách này. Viết mã tạo kernel có thể duy trì sẽ là một câu hỏi tiếp theo thú vị. Tôi có kinh nghiệm trong việc này, nhưng tôi sẽ không coi mình là người có thẩm quyền.
Aron Ahmadia

12

Đó là một câu hỏi về những gì bạn dành thời gian của bạn vào. Đối với hầu hết chúng ta, chúng ta dành 3/4 thời gian để lập trình và 1/4 thời gian chờ đợi kết quả. (Số của bạn có thể thay đổi, nhưng tôi nghĩ rằng số này không hoàn toàn không có giá trị.) Vì vậy, nếu bạn có một thiết kế cho phép bạn lập trình nhanh gấp đôi (3/4 đơn vị thời gian thay vì 1,5 đơn vị thời gian), thì bạn có thể đạt 300% hiệu suất (từ 1/4 đến 1 đơn vị thời gian) và bạn vẫn đi trước về thời gian thực dành cho việc giải quyết vấn đề.

Mặt khác, nếu bạn đang thực hiện các tính toán nặng nề, các tính toán của bạn có thể trông khác đi và bạn có thể muốn dành nhiều thời gian hơn để tối ưu hóa mã của mình.

Đối với tôi, 20% có vẻ như là một sự đánh đổi khá tốt nếu cuối cùng bạn làm việc hiệu quả hơn.


Câu trả lời tốt, tôi cũng thêm tầm quan trọng khi hiệu suất quan trọng. Một mã khoa học nhất định không thực hiện phép nhân ma trận; nếu 20% thời gian chạy của bạn là nhân ma trận, thì hiệu suất 20% đạt được chỉ có sự khác biệt 4% về tổng thể và tôi sẵn sàng lấy đó để đổi lấy một thư viện dễ sử dụng hơn.
Aurelius

1
Và một thư viện bằng văn bản tốt hơn có nghĩa là ít lỗi hơn, để bạn giảm bớt thời gian chờ đợi kết quả không chính xác.
Davidmh

4

IMHO một hình phạt lên tới 50% (vì bất kỳ lý do gì) không phải là xấu.

Trong thực tế, tôi đã thấy sự khác biệt 0-30% về hiệu suất chỉ dựa trên loại trình biên dịch. Điều này là dành cho thói quen MatMult thưa thớt của PETSc trên các ma trận phát sinh từ sự phân biệt FE theo thứ tự thấp.


1

Thiết kế phần mềm sẽ không tự động cải thiện theo thời gian. Việc thực hiện sẽ. Bạn sẽ nhận lại 20% với CPU tiếp theo của mình. Bên cạnh đó, thiết kế phần mềm tốt sẽ giúp mở rộng hoặc cải thiện thư viện trong tương lai dễ dàng hơn.


Tôi không nghĩ rằng điều này trả lời câu hỏi.
nicoguaro

0

Một nguyên tắc chung là trước tiên hãy thiết kế tốt và sau đó chỉ tối ưu hóa hiệu suất nếu cần . Các trường hợp sử dụng mà mức tăng hiệu suất 20% thực sự cần thiết có vẻ khá hiếm, nếu chúng xuất hiệ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.