2010-11-04 26 views
12

Tôi phát triển mã Lattice Boltzmann (Động lực học chất lỏng) bằng F #. Bây giờ tôi đang thử nghiệm mã trên 24 lõi, máy chủ bộ nhớ 128 GB. Mã này về cơ bản bao gồm một hàm đệ quy chính cho sự phát triển thời gian và bên trong một vòng lặp System.Threading.Tasks.Parallel.For cho một không gian 3D chiều. Không gian 3D là 500x500x500 lớn và một chu kỳ thời gian mất bao giờ :).F # dưới dạng ngôn ngữ HPC

let rec timeIterate time = 
    // Time consuming for loop 
    System.Threading.Tasks.Parallel.For(...) 

Tôi hy vọng máy chủ sẽ sử dụng tất cả 24 lõi để sử dụng 100%. Những gì tôi quan sát là một cái gì đó giữa 1% - 30% sử dụng.

Và câu hỏi của tôi là:

  1. là F # là một công cụ thích hợp để tính toán HPC trên các máy chủ như vậy?
  2. Thực tế có sử dụng tới 100% CPU cho một vấn đề thực tế không?
  3. Tôi nên làm gì để đạt được tốc độ cao? Tất cả mọi thứ là trong một lớn song song cho vòng lặp vì vậy tôi mong rằng đó là tất cả những gì tôi nên làm ...
  4. Nếu F # KHÔNG phải là một ngôn ngữ thích hợp, ngôn ngữ là gì?

Cảm ơn bạn đã đề xuất.

EDIT: Tôi sẵn sàng chia sẻ mã nếu có ai muốn xem.

EDIT2: Đây là phiên bản rút gọn của mã: http://dl.dropbox.com/u/4571/LBM.zip Nó không làm bất cứ điều gì hợp lý và tôi hy vọng tôi đã không giới thiệu bất kỳ lỗi bằng cách tách mã :)

Các tập tin khởi động là ShearFlow.fs và tại đáy hồ sơ là

let rec mainLoop (fA: FArrayO) (mR: MacroResult) time = 
    let a = LBM.Lbm.lbm lt pA getViscosity force g (fA, mR) 
+2

Đây có phải là ấm (thread. NET mất một ít thời gian để làm nóng và nhận đủ chủ đề) không? Bạn đang làm bất kỳ I/O chặn nào? Bạn đã thực hiện bất kỳ hồ sơ bộ nhớ nào để xem liệu bộ thu gom rác có phải là nút cổ chai không? Bạn đã làm hồ sơ gì (VS có các công cụ dễ sử dụng tuyệt vời)? – Brian

+2

Tôi nghi ngờ sử dụng bộ nhớ cache xấu. Bạn có chia lưới để mỗi lõi có được dữ liệu được bản địa hóa không? – CodesInChaos

+0

Tôi không phải là chuyên gia lập trình. Tôi không lưu bất kỳ tệp nào ngay bây giờ. Tôi đã cố gắng chạy thuật sĩ hiệu suất nhưng tôi không biết làm thế nào để làm hồ sơ bộ nhớ. Tôi sẽ phải kiểm tra điều đó. Tôi không chia lưới. Hiện tại, chúng tôi không mong đợi có mạng lưới lớn hơn 50x50x50. 500x500x500 chỉ là một ví dụ. Tôi đã thêm mã của tôi cho những người quan tâm :). –

Trả lời

5

1. F # có phải là công cụ thích hợp để tính toán HPC trên các máy chủ đó không?

Nó (F #), như một ngôn ngữ, thể khuyến khích mã mà hoạt động tốt trong song song - ít nhất là một phần của việc này là làm giảm các chức năng mutability nhà nước và bậc cao - đây là một thể và không phải là sẽ. Tuy nhiên, với HPC có nhiều ngôn ngữ lập trình đặc biệt/trình biên dịch và/hoặc cách phân phối tải (ví dụ: bộ nhớ được chia sẻ chung hoặc các hạt nhân phân tán). F # chỉ là ngôn ngữ lập trình có mục đích chung: có thể hoặc không có quyền truy cập (ví dụ: các ràng buộc có thể hoặc không tồn tại) với các kỹ thuật khác nhau. (Điều này áp dụng ngay cả đối với máy tính song song không phân phối.)

2. Có thực tế khi sử dụng tới 100% CPU cho một vấn đề thực tế?

Tùy thuộc vào yếu tố giới hạn. Nói chuyện với bạn tôi, những người thực hiện 5k + 100k + nghiên cứu và phát triển HPC lõi, việc trao đổi dữ liệu và thời gian nhàn rỗi thường là yếu tố hạn chế (tất nhiên, đây là n :-) cao hơn nhiều trong IO giảm (hiệu quả hoặc thuật toán khác nhau) có thể dẫn đến lợi ích đáng kể. Đừng quên chi phí chỉ đơn giản là di chuyển dữ liệu giữa CPU/cache trên cùng một máy! Và, tất nhiên, đĩa luôn chậm chạp ...

3. Tôi nên làm gì để đạt được tốc độ cao? Tất cả mọi thứ là trong một song song lớn cho vòng lặp vì vậy tôi sẽ mong đợi rằng đó là tất cả những gì tôi nên làm ...

Tìm hiểu xem (các) phần chậm là() và sửa lỗi (chúng): -) Ví dụ chạy phân tích tiểu sử. Hãy nhớ rằng nó có thể yêu cầu sử dụng một thuật toán hoặc cách tiếp cận hoàn toàn khác.

4. Nếu F # KHÔNG phải là ngôn ngữ thích hợp, ngôn ngữ nào là?

Trong khi tôi không cãi nhau cho nó, bạn tiến sĩ của tôi sử dụng/hoạt động trên Charm++: nó là một ngôn ngữ rất tập trung cho tính toán song song phân phối (không phải là môi trường trong câu hỏi, nhưng tôi đang cố gắng để làm cho một điểm: -) - F # cố gắng trở thành một ngôn ngữ có mục đích chung.

3

là F # là một công cụ thích hợp để tính toán HPC trên các máy chủ như vậy?

Tôi không biết F # rất nhiều nhưng tôi thà nghi ngờ rằng nó khá là cũng phù hợp. Nó có tất cả các công cụ phù hợp và đó là một ngôn ngữ chức năng cho phép thực thi song song cao.

Thực tế có sử dụng tới 100% CPU cho vấn đề thực tế không?

Có hoặc rất gần. Nhưng trên thực tế, ứng dụng của bạn nên sử dụng 2400% công suất CPU nếu bạn có 24 lõi! Ít nhất, đó là cách nó thường được hiển thị. Nếu bạn quan sát 30% mức sử dụng, rất có thể, nó đang chạy trên một lõi đơn và thậm chí không sử dụng lõi đó.

Tôi nên làm gì để đạt được tốc độ cao? Mọi thứ đều ở trong một vòng lặp lớn song song vì vậy tôi mong rằng đó là tất cả những gì tôi nên làm ...

Vâng, bạn không hiển thị mã của mình. Tôi chỉ có thể giả định rằng một cái gì đó trong mã của bạn ngăn không cho nó được thực hiện song song.

Cách khác (điểm sử dụng CPU từ 1% đến 30%) vấn đề của bạn không thực sự tính toán giới hạn, và tính toán là tất cả thời gian chờ đợi các tài nguyên khác như bộ nhớ phụ. Điều này không nhất thiết phụ thuộc vào vấn đề - sau khi tất cả, động lực học chất lỏng một vấn đề về tính toán! - nhưng thay vì thực hiện cụ thể của bạn. Cho đến nay, rất nhiều điểm để tranh tài tài nguyên.

+0

Tôi không biết về bạn, nhưng sử dụng 2 lõi đầy đủ trên lõi tứ hiển thị ở mức sử dụng 50% cho tôi, không phải 200%. Tôi nghi ngờ số 30% là 30% tổng số sử dụng cốt lõi không phải là 30% của 1 lõi. – Davy8

+0

@ Dợn sóng: hmm. Có lẽ điều này phụ thuộc vào hệ thống. Trên các hệ thống Unix, các công cụ như 'top' và' htop' hiển thị mức sử dụng CPU tổng thể trong bộ xử lý% lần. Nghĩa là, bộ xử lý lõi * X * sẽ có tải CPU tối đa * X * * 100%, không chỉ 100%. Busing một lõi đơn sẽ hiển thị lên đến 100%, bất kể số lõi trong máy. –

+0

@Konrad Ah, trên các máy windows, nó hiển thị% của tổng số và trên một tab riêng biệt có đồ thị cho mỗi lõi riêng lẻ. Một ứng dụng đơn luồng sẽ giúp tôi sử dụng tối đa 25% trên lõi tứ của mình. – Davy8

4

F # phải tốt bằng mọi ngôn ngữ. Đó là cách bạn viết mã của bạn hơn chính ngôn ngữ xác định hiệu suất.

Bạn sẽ có thể đến gần 100%, ít nhất là trong phạm vi 90% cao nếu tính toán của bạn là CPU bị ràng buộc.

Có thể có một số lý do khiến bạn không nhận được CPU 100% tại đây.

  1. tính của bạn có thể là I/O bound (đừng bạn nộp hoặc các hoạt động mạng trong vòng lặp for?)
  2. Bạn phải có vấn đề đồng bộ hóa như đến nhiều khóa (làm bạn đã chia sẻ trạng thái giữa các chủ đề, bao gồm nơi bạn "cam kết" kết quả?)
+0

Ngoài ra, nếu sử dụng các tập dữ liệu lớn, nó có thể là bus bộ nhớ bị ràng buộc - các lõi đang dành phần lớn thời gian chờ đợi trên bộ nhớ chính. Nếu điều này được kết hợp với các dòng bộ nhớ cache nóng (nghĩa là nhiều CPU cố gắng khóa cùng một dòng bộ nhớ cache cùng lúc) thì việc thực hiện sẽ bị lỗi. – Richard

+1

@Richard, quản lý bộ nhớ có thực sự quan trọng khi bạn nhận được quyền song song cơ bản.Chính xác tôi nếu tôi sai, nhưng tôi nghĩ rằng Windows sẽ báo cáo chờ đợi bộ nhớ/bộ nhớ cache như sử dụng CPU đầy đủ. –

+0

Có cách nào đơn giản làm thế nào để kiểm tra và tránh ranh giới bus bộ nhớ? –

2
  1. tôi không nghĩ rằng F # vẫn chưa làm cho nó vào dòng chính của HPC, nơi Fortran, C và C++ chiếm ưu thế, nhưng tôi không thấy bất kỳ lý do cụ thể tại sao bạn nên tránh nó.

  2. Không, không phải, không phải cho bất kỳ khoảng thời gian dài nào. Sớm hay muộn tất cả (khẳng định có vấn đề) Mã HPC trở thành băng thông bộ nhớ bị giới hạn - CPU có thể khủng hoảng số nhanh hơn rất nhiều so với RAM có thể tải và lưu trữ. Trên một tính toán dài, bạn đang làm tốt để sử dụng 10% số lượng tối đa lý thuyết của FLOPs mà CPU của bạn có thể thực thi.

  3. Tôi thực sự không biết F # đủ tốt để cung cấp lời khuyên cụ thể cho cấu hình của bạn (Tôi là một trong những lập trình viên HPC Fortran). Nhưng nói chung, bạn cần đảm bảo cân bằng tải tốt (tức là tất cả các lõi đều làm cùng một lượng công việc), sử dụng hiệu quả hệ thống phân cấp bộ nhớ (rất khó khăn khi các ngôn ngữ nhận được 'cấp cao hơn' vì chúng có xu hướng gây khó khăn để quản lý các quy trình ở mức thấp) và điều tốt nhất bạn có thể làm là chọn thuật toán tốt nhất. Thuật toán song song tốt nhất không nhất thiết phải là thuật toán nối tiếp tốt nhất được thực hiện song song, và tôi nghi ngờ rằng thuật toán (thực hiện) một chức năng tốt nhất có thể không phải là thuật toán tốt nhất (bắt buộc thực hiện).

  4. Fortran.

+1

"sử dụng hiệu quả phân cấp bộ nhớ". ** CÓ! ** "Fortran". ** NO! ** –

+2

@Jon Harrop: bạn nói đúng, tôi sẽ thả Fortran ngay lập tức, tôi mong mọi người khác trong cộng đồng HPC cũng vậy. –

0

Bạn đã thử sử dụng các công cụ phân tích luồng có trong Visual Studio: sử dụng tùy chọn lược tả đồng thời trong thuật sĩ hiệu suất không?

1

Nhóm chủ đề có số lượng chuỗi tối đa tùy thuộc vào các trường hợp khác nhau.

Từ MSDN:

tối đa Số Chủ đề Pool Chủ đề

Số lượng các hoạt động có thể được xếp hàng đợi đến hồ bơi thread được giới hạn bởi có sẵn> bộ nhớ; tuy nhiên, thread thread giới hạn số lượng các luồng có thể được kích hoạt trong quá trình đồng thời. Bắt đầu với.NET Framework phiên bản 4, kích thước mặc định của hồ bơi thread cho một quá trình phụ thuộc vào một số yếu tố, chẳng hạn như kích thước của địa chỉ ảo> không gian. Một quá trình có thể gọi phương thức GetMaxThreads để xác định số lượng các luồng.

Bạn có thể kiểm soát số lượng chuỗi tối đa bằng cách sử dụng phương thức GetMaxThreads và SetMaxThreads.

Ngoài ra hãy thử nâng cấp MinThread, nếu cần. Lượng lõi trên hệ thống của bạn có thể đang ném thuật toán tối ưu hóa Threadpool? Đáng thử.

Một lần nữa, từ MSDN:

Những hồ bơi thread cung cấp đề người lao động mới hoặc I/O đề hoàn thành theo yêu cầu cho đến khi nó đạt đến một mức tối thiểu quy định cho từng loại. Bạn có thể sử dụng phương thức GetMinThreads để có được các giá trị tối thiểu này.

Khi đạt đến mức tối thiểu, nhóm chủ đề có thể tạo chủ đề bổ sung hoặc đợi cho đến khi một số tác vụ hoàn tất. Bắt đầu với .NET Framework 4, pool thread tạo và hủy các luồng công nhân để tối ưu hóa thông lượng, được định nghĩa là số nhiệm vụ hoàn thành trên một đơn vị thời gian. Quá ít luồng có thể không sử dụng tối ưu các tài nguyên có sẵn, trong khi quá nhiều luồng có thể làm tăng sự tranh chấp tài nguyên.

+0

GetMaxThreads trên máy chủ truy xuất 32767, 1000 –

+1

@Oldrich Svec Tôi đã cập nhật câu trả lời bằng giải pháp thay thế có thể có. –

1

Lập trình chức năng tập trung vào việc trừu tượng hóa cấp cao, tức là bạn tóm tắt các mẫu lập trình chung và làm cho chúng có thể sử dụng lại được. Tính toán hiệu suất cao là về việc làm cho mọi thứ chạy song song, suy nghĩ về các bit giữa các luồng khác nhau, suy nghĩ về vị trí dữ liệu để làm cho bộ nhớ cache đạt mức cao. Đây là hai hướng khác nhau.

Ngày nay, mọi người có xu hướng nghĩ FP như một viên đạn bạc cho mọi thứ song song, bao gồm cả tính toán hiệu suất cao. KHÔNG. Nếu không, bạn sẽ thấy rất nhiều giấy tờ FP được công bố trong các hội thảo hiệu suất cao. Trên thực tế khá ít.

Bạn đang sử dụng thư viện Task Parallel, thư viện .Net cho C#/F #/VB. Không F # cụ thể. Mà chính nó được viết bằng C#, tôi tin.

Với ý nghĩ này, hãy quay lại câu hỏi của bạn. Tại sao bạn không thể sử dụng CPU 100%? Các kỹ năng giúp bạn tìm thấy các nút cổ chai có ít hơn để làm với F #. Làm một hồ sơ của chương trình của bạn, xem liệu một số chủ đề đang chờ đợi những người khác để hoàn thành (bạn cần phải hoàn thành tất cả các máy tính trong Paralle.For để tiếp tục).

+0

+1 cho "Nếu không, bạn sẽ thấy rất nhiều giấy tờ FP được xuất bản trong các hội thảo hiệu suất cao". –

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