Ở mức độ nào thì việc lập trình chung và lập trình meta sử dụng các mẫu C ++ hữu ích trong khoa học tính toán?


17

Ngôn ngữ C ++ cung cấp lập trình chungsiêu lập trình thông qua các mẫu. Những kỹ thuật này đã tìm được đường vào nhiều gói máy tính khoa học quy mô lớn (ví dụ: MPQC , LAMMPS , CGAL , Trilinos ). Nhưng những gì họ đã thực sự đóng góp cho tính toán khoa học về giá trị vượt xa các ngôn ngữ không chung chung, phi meta như C hoặc Fortran về thời gian phát triển tổng thể và khả năng sử dụng cho hiệu quả tương đương hoặc đầy đủ?

Được giao một nhiệm vụ tính toán khoa học, việc lập trình chung và lập trình meta thông qua các mẫu C ++ đã cho thấy sự cải thiện về năng suất, tính biểu cảm hay khả năng sử dụng được đo bằng bất kỳ điểm chuẩn nào được hiểu rõ (dòng mã, nỗ lực cá nhân, v.v ...)? Tương ứng, những rủi ro nào liên quan đến việc sử dụng các mẫu C ++ cho lập trình chung và siêu lập trình?


Tôi lo ngại rằng câu hỏi này có thể quá cởi mở với các ý kiến, nhưng tôi muốn xem mọi người trong cộng đồng nói gì.
Geoff Oxberry

1
Tôi hoàn toàn xóa bình luận trật bánh. Nếu bạn muốn nó được đăng lại để trò chuyện hoặc meta, tôi rất vui lòng làm điều đó. Xem meta của tôi ở đây .
Aron Ahmadia

3
Ngoài ra, hãy xem câu hỏi liên quan ở đây về lời khuyên khi nào nên sử dụng và khi nào nên tránh các mẫu biểu thức .
Aron Ahmadia

Tôi không nghĩ rằng việc LAMMPS sử dụng các mẫu hoặc siêu lập trình là chính xác. LAMMPS là mã hướng đối tượng, trông rất giống với Fortran hầu hết thời gian. Tôi không nghĩ MPQC cũng có nhiều khuôn mẫu, nhưng nó mang tính đa hình và hướng đối tượng.
Jeff

1
OpenFOAM sử dụng rất nhiều mẫu và các tính năng khác của C ++.
Dohn Joe

Câu trả lời:


14

Tôi nghĩ và nhìn chung, siêu lập trình mẫu đã được tìm thấy là không sử dụng được trong thực tế - nó biên dịch quá chậm và các thông báo lỗi chúng tôi nhận được là không thể giải mã được. Rào cản gia nhập cho người mới cũng chỉ là quá cao khi sử dụng siêu lập trình.

Tất nhiên, lập trình chung là một vấn đề hoàn toàn khác, như được chứng kiến ​​bởi Trilinos, deal.II (thư viện của riêng tôi), DUNE và nhiều thư viện khác - thể hiện cùng một khái niệm hoạt động trên các loại dữ liệu khác nhau là không có trí tuệ, và cộng đồng phần lớn đã chấp nhận nó miễn là nó nằm trong giới hạn tránh các vấn đề của siêu lập trình. Tôi nghĩ rằng lập trình chung đủ điều kiện là một thành công rõ ràng.

Tất nhiên, cả hai chủ đề này đều không được kết nối ngay lập tức với OOP. OOP, một lần nữa, tôi muốn nói, được cộng đồng máy tính khoa học chấp nhận rộng rãi. Thậm chí ít hơn lập trình chung, đó không phải là một chủ đề tranh luận: mọi thư viện thành công được viết trong 15 năm qua (dù được viết bằng C ++, C hay Fortran) đều sử dụng các kỹ thuật OOP.


4
tmp có thể khó khăn cho người dùng mới làm quen, nhưng nó thường được thực hiện rất tốt trong thư viện. Đây là một trong những kỹ thuật thực sự có thể làm giảm số lượng mã nhưng bạn thực sự cần phải biết những gì bạn đang làm. Nếu bạn không tin tôi hãy đọc nguồn Eigen hoặc Elemental. Mã đẹp mà không có mẫu sẽ không thể thực hiện được.
aterrel

5
Chắc chắn, đó là một kỹ thuật có giá trị. Nhưng nó khó bảo trì và thường khó sử dụng nếu tiếp xúc với giao diện bên ngoài. Điều đó nói rằng, tôi nghĩ một trong những lý do TMP không hoàn toàn là thành công mà mọi người có thể mong đợi ban đầu là trình biên dịch đã trở nên rất tốt. TMP sống thực tế là có rất nhiều thứ được biết đến vào thời gian biên dịch, và sau đó có thể được truyền dưới dạng hằng số vào mã thực tế. Nhưng trình biên dịch đã trở nên khá tốt trong việc nội tuyến, nhân bản hàm, v.v. và vì vậy một phần lợi ích đáng kể ngày nay có thể thu được bằng cách sử dụng lập trình "bình thường".
Wolfgang Bangerth

15

Hãy để tôi đưa ra một ví dụ dựa trên kinh nghiệm. Hầu hết các thư viện tôi sử dụng hàng ngày đều sử dụng OOP theo một cách nào đó. OOP có thể che giấu sự phức tạp cần thiết cho nhiều tên miền, nó không phải là một cơ chế thực sự giúp ích cho hiệu suất. Điều có thể xảy ra là một thư viện có thể sử dụng các tối ưu hóa cụ thể dựa trên hệ thống phân cấp đối tượng, nhưng phần lớn là về việc che giấu sự phức tạp từ người dùng. Tra cứu các mẫu thiết kế, chúng là các cơ chế thường được sử dụng để thực hiện việc ẩn giấu phức tạp này.

Lấy PETSc làm ví dụ. PETSc sử dụng mô hình thanh tra / thực thi của OOP trong đó bất kỳ thuật toán nào của nó nhìn vào các thói quen có sẵn trong một đối tượng nhất định, sẽ chọn cách thực hiện để thực hiện thói quen. Điều này cho phép người dùng phân tách các mối quan tâm, ví dụ hành động ma trận có thể bao gồm bất kỳ loại thói quen bị chặn hoặc tối ưu hóa nào và được sử dụng hiệu quả bởi nhiều bộ giải lặp. Bằng cách cung cấp cho người dùng khả năng chỉ định các loại dữ liệu và đánh giá của riêng họ, họ có được một vài thói quen quan trọng được tăng tốc và cũng có sẵn toàn bộ chức năng của thư viện.

Một ví dụ khác tôi sẽ đưa ra là FEniCS và deal.II. Cả hai thư viện này đều sử dụng OOP để khái quát hóa qua một số lượng lớn Phương thức phần tử hữu hạn. Trong cả hai thứ từ loại phần tử, thứ tự phần tử, biểu diễn bậc hai, v.v đều có thể hoán đổi cho nhau. Mặc dù cả hai thư viện này đều "chậm" hơn một số mã FEM có cấu trúc đặc biệt, chúng có thể giải quyết nhiều vấn đề khác nhau với phần lớn sự phức tạp của FEM mà người dùng chưa biết.

Ví dụ cuối cùng của tôi là Elemental. Elemental là một thư viện đại số tuyến tính dày đặc mới gặp khó khăn trong việc quản lý các bộ truyền thông MPI và vị trí dữ liệu thành một cấu trúc ngôn ngữ rất đơn giản. Kết quả là nếu bạn có mã nối tiếp FLAME, bằng cách thay đổi kiểu dữ liệu, bạn cũng có thể có mã song song qua Elemental. Thậm chí thú vị hơn, bạn có thể chơi với phân phối dữ liệu bằng cách đặt phân phối bằng với phân phối khác.

OOP nên được coi là một cách để quản lý sự phức tạp, không phải là một mô hình để cạnh tranh với lắp ráp bằng tay. Ngoài ra, làm việc đó kém sẽ dẫn đến rất nhiều chi phí, do đó người ta phải giữ thời gian và cập nhật các cơ chế mà họ sử dụng.


3

Những tính năng ngôn ngữ nào giống như OOPlàm cho máy tính khoa học là tạo ra các câu lệnh mã nhỏ gọn hơn giúp hiểu và sử dụng mã tốt hơn. Ví dụ, FFTcác thường trình cần mang một số lượng lớn các đối số cho mỗi lệnh gọi hàm làm cho mã trở nên cồng kềnh.

Bằng cách sử dụng modulehoặc classchỉ báo cáo những gì cần thiết tại thời điểm cuộc gọi có thể được thông qua, vì phần còn lại của các đối số liên quan đến thiết lập vấn đề (nghĩa là kích thước của mảng và hệ số).

Theo kinh nghiệm của tôi, tôi đã có SUBROUTINEcác cuộc gọi với 55 đối số (vào & ra) và tôi đã giảm xuống còn 5 để làm cho mã tốt hơn.

Đó là giá trị.


3

Tôi là một người ủng hộ mạnh mẽ của lập trình chung và lập trình meta cho máy tính khoa học. Tôi thực sự đang phát triển một thư viện C ++ phần mềm miễn phí cho các phương thức Galerkin dựa trên các kỹ thuật được gọi là Feel ++ (http://www.feelpp.org) đang dần có được động lực. Đúng là vẫn còn những khó khăn như thời gian biên dịch chậm và đường cong học tập có thể dốc nếu người ta muốn hiểu những gì đang diễn ra đằng sau hậu trường. Điều này là tuy nhiên vô cùng thú vị và tâm trí thổi. Nếu được thực hiện ở cấp thư viện và che giấu sự phức tạp đằng sau một ngôn ngữ cụ thể của miền, bạn sẽ có được một công cụ cực kỳ mạnh mẽ. Chúng tôi có sẵn một phạm vi rất rộng một phương pháp để sử dụng và so sánh. Đối với mục đích giảng dạy của máy tính khoa học, điều này thật tuyệt vời, cho nghiên cứu và phương pháp số mới, cho các ứng dụng quy mô lớn, chúng tôi làm việc với nó nhưng cho đến nay rất tốt, chúng tôi đã có thể làm một số thứ tốt đẹp. Chúng tôi có các kỹ sư, nhà vật lý và nhà toán học sử dụng nó: hầu hết trong số họ chỉ sử dụng ngôn ngữ cho công thức đa dạng và họ hài lòng với nó. Nhìn vào một số công thức mà các đồng nghiệp vật lý của chúng tôi thao tác, tôi sẽ không muốn thấy chúng được thực hiện "bằng tay" mà không có ngôn ngữ cấp cao để mô tả công thức biến đổi. Cá nhân tôi cho rằng các "kỹ thuật" hoặc "mô hình" này hiện đang cần thiết để giải quyết sự phức tạp trong mã máy tính khoa học với việc phải nhân kích thước mã với một yếu tố rất lớn. Đáng chú ý là cần phải cải thiện sự hỗ trợ của lập trình meta trong C ++ nhưng nó đã ở trạng thái tốt, đặc biệt là từ C ++ 11.


2

Bạn có thể tìm thấy bài báo http://arxiv.org/abs/1104.1729 có liên quan đến câu hỏi của bạn. Nó thảo luận về các mẫu biểu thức (một ứng dụng cụ thể của lập trình meta mẫu được sử dụng trong mã khoa học) từ góc độ hiệu năng.


Tờ giấy đó khiến tôi phát điên. So sánh Fortran đồng bằng nhanh nhất bạn có với MKL và nó cũng sẽ mất. Lắp ráp điều chỉnh bằng tay không phải là thứ mà người ta khao khát, đó là những gì bạn làm khi mỗi nano giây được tính và có thể được sử dụng lại bởi một số lượng rất lớn mọi người.
aterrel

@aterrel: Đây chính xác là sự tương phản mà tôi đang tự hỏi. Biết rằng bạn sẽ phải thực hiện tối ưu hóa bằng tay như là giai đoạn phát triển cuối cùng, bạn sẽ chọn ngôn ngữ nào làm cơ sở để sử dụng trước giai đoạn cuối? Chúng ta có dữ liệu cứng để đề xuất ngôn ngữ nào để chọn không?
Deathbreath

9
@Deathbreath: Tôi cũng sẽ lặp lại một câu trả lời tôi đã thực hiện trên một số chủ đề khác - rằng, nói chung, điều chỉnh chút tốc độ cuối cùng ra khỏi mã của bạn là điều bạn rất hiếm khi làm. Nhưng bạn lập trình các thuật toán cấp cao mọi lúc. Vì vậy, chọn ngôn ngữ cho phép bạn làm những việc lớn một cách nhanh chóng. Luôn luôn có một cách để bao gồm các công cụ cấp thấp bằng cách nào đó, nhưng nó không phải là thứ quyết định sự lựa chọn ngôn ngữ lập trình của bạn.
Wolfgang Bangerth

0

Mẫu rất tốt trong việc loại bỏ kiểm tra loại / tên miền tại thời gian chạy. Đây có thể được chăm sóc tại thời gian biên dịch. Về lý thuyết, điều này có thể làm tăng hiệu suất so với cùng loại thực hiện trong C hoặc Fortran khi việc kiểm tra loại chỉ có thể được thực hiện trong thời gian chạy - kiểm tra được thực hiện trong mã nguồn. Tuy nhiên, bạn có thể đạt được kết quả tương tự trong C bằng cách sử dụng các tùy chọn trình biên dịch trước nhưng chúng phải được thực hiện bằng tay không giống như các mẫu.

Tuy nhiên, các mẫu có thể tạo ra chi phí đáng kể quá. Họ thường có thể tạo phình mã có thể ảnh hưởng đến việc sử dụng bộ đệm hướng dẫn. Hơn nữa, các cách tiếp cận chung thường có thể xiềng xích trình biên dịch trong quá trình tối ưu hóa - không phải lúc nào cũng dễ dàng phân tích mã khi sử dụng các cách tiếp cận chung. Nó luôn luôn là một vấn đề với tự động hóa - bao gồm tối ưu hóa trình biên dịch - rất thường mã đầu ra không thân thiện với bộ đệm.

Lợi ích của việc kiểm tra loại / tên miền, mặc dù chắc chắn an toàn hơn, là lợi ích thực sự duy nhất tôi có thể thấy về mặt hiệu suất và những điều này thường không thể chấp nhận được. Nhưng như tôi nói, hiệu ứng tổng thể có thể tiêu cực tùy thuộc vào những gì bạn đang làm. Đó là lý do tại sao thường tốt hơn để tối ưu hóa mã của bạn, nơi bạn có các tắc nghẽn đáng kể.

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.