Phần mềm khoa học không có nhiều khác biệt so với các phần mềm khác, về cách biết những gì cần điều chỉnh.
Phương pháp tôi sử dụng là tạm dừng ngẫu nhiên . Đây là một số tốc độ mà nó đã tìm thấy cho tôi:
Nếu một phần lớn thời gian được dành cho các hàm như log
và exp
, tôi có thể thấy các đối số cho các hàm đó là gì, như là một hàm của các điểm mà chúng được gọi từ đó. Thông thường họ đang được gọi nhiều lần với cùng một lập luận. Nếu vậy, ghi nhớ tạo ra một yếu tố tăng tốc lớn.
Nếu tôi đang sử dụng các hàm BLAS hoặc LAPACK, tôi có thể thấy rằng một phần lớn thời gian được sử dụng trong các thói quen để sao chép mảng, nhân ma trận, biến đổi choleski, v.v.
Các thói quen để sao chép mảng không có ở đó cho tốc độ, nó là để thuận tiện. Bạn có thể thấy có một cách ít thuận tiện hơn, nhưng nhanh hơn, để làm điều đó.
Các thường trình để nhân hoặc đảo ngược ma trận, hoặc thực hiện các phép biến đổi choleski, có xu hướng có các đối số ký tự chỉ định các tùy chọn, chẳng hạn như 'U' hoặc 'L' cho tam giác trên hoặc dưới. Một lần nữa, đó là cho thuận tiện. Những gì tôi tìm thấy là, vì ma trận của tôi không lớn lắm, các thói quen đã dành hơn một nửa thời gian của họ để gọi chương trình con để so sánh các ký tự chỉ để giải mã các tùy chọn. Viết các phiên bản mục đích đặc biệt của các thói quen toán học tốn kém nhất đã tạo ra sự tăng tốc lớn.
Nếu tôi chỉ có thể mở rộng ở phần sau: DGEMM thường xuyên nhân ma trận gọi LSAME để giải mã các đối số ký tự của nó. Nhìn vào phần trăm thời gian bao gồm (giá trị thống kê duy nhất nhìn vào) các trình biên dịch được coi là "tốt" có thể hiển thị DGEMM bằng cách sử dụng một số phần trăm tổng thời gian, như 80% và LSAME sử dụng một số phần trăm tổng thời gian, như 50%. Nhìn vào cái trước, bạn sẽ bị cám dỗ để nói rằng "nó phải được tối ưu hóa rất nhiều, vì vậy tôi không thể làm gì nhiều về điều đó". Nhìn vào cái sau, bạn sẽ bị cám dỗ để nói "Huh? Tất cả những gì về nó? Đó chỉ là một thói quen nhỏ tuổi. Hồ sơ này phải sai!"
Điều đó không sai, nó chỉ không nói cho bạn biết những gì bạn cần biết. Điều tạm dừng ngẫu nhiên cho bạn thấy là DGEMM có trên 80% mẫu ngăn xếp và LSAME là trên 50%. (Bạn không cần nhiều mẫu để phát hiện ra. 10 thường là rất nhiều.) Hơn nữa, trên nhiều mẫu đó, DGEMM đang trong quá trình gọi LSAME từ một vài dòng mã khác nhau.
Vì vậy, bây giờ bạn biết tại sao cả hai thói quen đang mất rất nhiều thời gian. Bạn cũng biết nơi mà mã của bạn được gọi từ đâu để dành tất cả thời gian này. Đó là lý do tại sao tôi sử dụng tạm dừng ngẫu nhiên và có một cái nhìn vàng da về các trình biên dịch, bất kể chúng được làm tốt như thế nào. Họ quan tâm đến việc đo đạc hơn là nói cho bạn biết chuyện gì đang xảy ra.
Thật dễ dàng để giả định các thói quen thư viện toán học đã được tối ưu hóa đến mức thứ n, nhưng trên thực tế, chúng đã được tối ưu hóa để có thể sử dụng cho nhiều mục đích. Bạn cần phải xem những gì thực sự đang diễn ra, không phải là những gì dễ dàng để giả định.
THÊM: Vì vậy, để trả lời hai câu hỏi cuối cùng của bạn:
Những điều quan trọng nhất để thử đầu tiên là gì?
Lấy 10-20 mẫu ngăn xếp và không chỉ tóm tắt chúng, hiểu những gì mỗi người đang nói với bạn. Làm điều này đầu tiên, cuối cùng và ở giữa. (Không có "thử", Skywalker trẻ.)
Làm thế nào để tôi biết tôi có thể đạt được bao nhiêu hiệu suất?
xβ(s+1,(n−s)+1)sn1/(1−x)n=10s=5x
xx
Như tôi đã chỉ ra cho bạn trước đây, bạn có thể lặp lại toàn bộ quy trình cho đến khi bạn không thể làm được nữa và tỷ lệ tăng tốc gộp có thể khá lớn.
(s+1)/(n+2)=3/22=13.6%.) Đường cong dưới trong biểu đồ sau là phân phối của nó:
Hãy xem xét nếu chúng tôi đã lấy tới 40 mẫu (nhiều hơn tôi từng có một lần) và chỉ thấy một vấn đề ở hai trong số chúng. Chi phí ước tính (chế độ) của vấn đề đó là 5%, như thể hiện trên đường cong cao hơn.
"Dương tính giả" là gì? Đó là nếu bạn khắc phục một vấn đề bạn nhận ra mức tăng nhỏ hơn dự kiến, bạn sẽ hối tiếc vì đã sửa nó. Các đường cong cho thấy (nếu vấn đề là "nhỏ"), trong khi mức tăng có thể nhỏ hơn phần mẫu cho thấy nó, trung bình nó sẽ lớn hơn.
Có một rủi ro nghiêm trọng hơn nhiều - một "âm tính giả". Đó là khi có một vấn đề, nhưng nó không được tìm thấy. (Đóng góp cho điều này là "sự xác nhận thiên vị", trong đó sự vắng mặt của bằng chứng có xu hướng được coi là bằng chứng của sự vắng mặt.)
Những gì bạn nhận được với một hồ sơ (một cái tốt) là bạn có được phép đo chính xác hơn nhiều (do đó ít có khả năng dương tính giả), với chi phí thông tin ít chính xác hơn về vấn đề thực sự là gì (do đó ít có cơ hội tìm thấy và nhận được bất kỳ lợi ích). Điều đó giới hạn tốc độ tổng thể có thể đạt được.
Tôi sẽ khuyến khích người dùng trình biên dịch báo cáo các yếu tố tăng tốc mà họ thực sự có được trong thực tế.
Có một điểm khác sẽ được thực hiện lại. Câu hỏi của Pedro về dương tính giả.
Ông đã đề cập có thể có một khó khăn khi gặp các vấn đề nhỏ trong mã được tối ưu hóa cao. (Đối với tôi, một vấn đề nhỏ là một vấn đề chiếm 5% hoặc ít hơn tổng thời gian.)
Vì hoàn toàn có thể xây dựng một chương trình hoàn toàn tối ưu ngoại trừ 5%, điểm này chỉ có thể được giải quyết theo kinh nghiệm, như trong câu trả lời này . Để khái quát từ kinh nghiệm thực nghiệm, nó diễn ra như sau:
Một chương trình, như được viết, thường chứa một số cơ hội để tối ưu hóa. (Chúng ta có thể gọi chúng là "các vấn đề" nhưng chúng thường là mã hoàn toàn tốt, đơn giản là có khả năng cải thiện đáng kể.) Sơ đồ này minh họa một chương trình nhân tạo mất một khoảng thời gian (100 giây, nói) và nó chứa các vấn đề A, B, C, ... rằng, khi được tìm thấy và sửa chữa, hãy tiết kiệm 30%, 21%, v.v. của 100 bản gốc.
Lưu ý rằng vấn đề F tốn 5% thời gian ban đầu, vì vậy nó "nhỏ" và khó tìm thấy nếu không có 40 mẫu trở lên.
Tuy nhiên, 10 mẫu đầu tiên dễ dàng tìm thấy sự cố A. ** Khi điều đó được khắc phục, chương trình chỉ mất 70 giây, với tốc độ tăng tốc 100/70 = 1,43x. Điều đó không chỉ làm cho chương trình nhanh hơn, mà còn phóng to, theo tỷ lệ đó, tỷ lệ phần trăm được thực hiện bởi các vấn đề còn lại. Ví dụ: vấn đề B ban đầu mất 21 giây, chiếm 21% tổng số, nhưng sau khi loại bỏ A, B mất 21 trong số 70 hoặc 30%, do đó dễ dàng tìm thấy hơn khi toàn bộ quá trình được lặp lại.
Sau khi quá trình được lặp lại năm lần, bây giờ thời gian thực hiện là 16,8 giây, trong đó vấn đề F là 30%, không phải 5%, vì vậy 10 mẫu tìm thấy nó dễ dàng.
Vì vậy, đó là điểm. Theo kinh nghiệm, các chương trình chứa một loạt các vấn đề có sự phân bố kích thước và bất kỳ vấn đề nào được tìm thấy và khắc phục sẽ giúp bạn dễ dàng tìm thấy các vấn đề còn lại. Để thực hiện điều này, không có vấn đề nào có thể bỏ qua bởi vì, nếu có, họ ngồi đó mất thời gian, hạn chế tổng tốc độ và không phóng đại các vấn đề còn lại.
Đó là lý do tại sao nó rất quan trọng để tìm ra những vấn đề đang ẩn giấu .
Nếu các sự cố từ A đến F được tìm thấy và khắc phục, tốc độ tăng tốc là 100 / 11,8 = 8,5x. Nếu một trong số chúng bị bỏ lỡ, ví dụ D, thì tốc độ chỉ là 100 / (11.8 + 10.3) = 4.5x.
Đó là cái giá phải trả cho những tiêu cực giả.
Vì vậy, khi trình hồ sơ nói rằng "dường như không có vấn đề gì đáng kể ở đây" (tức là người viết mã giỏi, đây thực sự là mã tối ưu), có thể đúng, và có thể không. (Một phủ định sai .) Bạn không biết chắc chắn liệu có nhiều vấn đề cần khắc phục hay không, để tăng tốc độ cao hơn, trừ khi bạn thử một phương pháp định hình khác và phát hiện ra rằng có. Theo kinh nghiệm của tôi, phương pháp định hình không cần một số lượng lớn các mẫu, được tóm tắt, nhưng một số lượng nhỏ các mẫu, trong đó mỗi mẫu được hiểu thấu đáo đủ để nhận ra bất kỳ cơ hội nào để tối ưu hóa.
2/0.3=6.671 - pbinom(1, numberOfSamples, sizeOfProblem)
1 - pbinom(1, 20, 0.3) = 0.9923627
xβ(s+1,(n−s)+1)nsy1/(1−x)xyy−1Phân phối BetaPrime . Tôi đã mô phỏng nó với 2 triệu mẫu, đến hành vi này:
distribution of speedup
ratio y
s, n 5%-ile 95%-ile mean
2, 2 1.58 59.30 32.36
2, 3 1.33 10.25 4.00
2, 4 1.23 5.28 2.50
2, 5 1.18 3.69 2.00
2,10 1.09 1.89 1.37
2,20 1.04 1.37 1.17
2,40 1.02 1.17 1.08
3, 3 1.90 78.34 42.94
3, 4 1.52 13.10 5.00
3, 5 1.37 6.53 3.00
3,10 1.16 2.29 1.57
3,20 1.07 1.49 1.24
3,40 1.04 1.22 1.11
4, 4 2.22 98.02 52.36
4, 5 1.72 15.95 6.00
4,10 1.25 2.86 1.83
4,20 1.11 1.62 1.31
4,40 1.05 1.26 1.14
5, 5 2.54 117.27 64.29
5,10 1.37 3.69 2.20
5,20 1.15 1.78 1.40
5,40 1.07 1.31 1.17
(n+1)/(n−s)s=ny
Đây là một âm mưu phân phối các yếu tố tăng tốc và phương tiện của chúng, cho 2 lần truy cập trong số 5, 4, 3 và 2 mẫu. Ví dụ: nếu 3 mẫu được lấy và 2 trong số đó là các vấn đề và vấn đề đó có thể được loại bỏ, hệ số tăng tốc trung bình sẽ là 4 lần. Nếu chỉ nhìn thấy 2 lần truy cập trong 2 mẫu, thì tốc độ trung bình không được xác định - về mặt khái niệm vì các chương trình có vòng lặp vô hạn tồn tại với xác suất khác không!