(Làm thế nào) bạn có tính đến phân mảnh bộ nhớ?


8

Tôi sử dụng một ví dụ từ lý thuyết phần tử hữu hạn, nhưng bất kỳ ai duy trì cơ sở hạ tầng lớn và liên tục mở rộng nó sẽ tìm thấy một cái gì đó tương tự.

Giả sử tôi có một lưới các điểm và tam giác không cấu trúc, trong đó các điểm được cho bởi tọa độ (giả sử y ) và các tam giác đều bao gồm ba chỉ số điểm (giả sử i , jk ).xyTôijk

Như phổ biến trong FEM, lưới sẽ được tinh chế liên tiếp. Nếu chúng ta sử dụng sàng lọc thường xuyên toàn cầu, số lượng tam giác sẽ tăng theo hệ số với mỗi lần lặp của sàng lọc. Tùy thuộc vào cách thực hiện, bố cục bộ nhớ sẽ phát triển khác nhau.4

Nói rằng lưới thỉnh thoảng có các ô nhớ từ 1 đến 300, bất cứ thứ gì ngoài đó đều miễn phí.

Ví dụ 1:

Chúng tôi phân bổ không gian cho lưới mới, các ô từ 301 đến 1501, điền vào dữ liệu của lưới tinh chế và quên đi lưới cũ. Lưới tinh chế tiếp theo sẽ được đặt trong các ô từ 1501 đến 6300, lưới tiếp theo trong 6301 đến 21500, v.v. Vị trí của lưới hiện tại sẽ di chuyển trong bộ nhớ "sang phải", trong khi một miếng vá lớn sẽ không được sử dụng. Chúng tôi có thể hết bộ nhớ sớm.

Người ta có thể quan sát trong ví dụ trên, rằng điều này sẽ chỉ cản trở chúng ta trong một lần sàng lọc, bởi vì ngay cả khi không có sự phân mảnh đó, chúng ta sẽ hết bộ nhớ một lần tinh chỉnh sau đó. Khi mảng đỉnh cũng được tính đến, vấn đề có thể trở nên nghiêm trọng hơn.

Làm thế nào điều này có thể được phá vỡ?

Ví dụ 2:

Tái định vị mảng tam giác cho các ô 1..1200. Tạo lưới mới trong các ô 1201 đến 2400. Sao chép nội dung của bản sao làm việc đó vào các ô 1..1200 và quên bản sao làm việc. Lặp lại tương tự.

Ok, chúng tôi vẫn hết bộ nhớ sớm, bởi vì chúng tôi cần một bản sao làm việc. Còn cái này thì sao:

Ví dụ 3:

Tái định vị mảng tam giác cho các ô 1..1500. Sao chép lưới cũ vào 1201 .. 1500. Tạo lưới mới trong các ô 1..1200. Sau đó quên bản sao của lưới cũ.

Trường hợp ở đây là nhân tạo, bởi vì người ta sẽ không sử dụng sàng lọc lưới toàn cầu trên các quy mô này. Nếu sự tăng trưởng nhỏ hơn nhiều, việc sắp xếp lại bộ nhớ là có thể để tránh sự phân mảnh. Tuy nhiên,

Câu hỏi:

  1. Sự phân mảnh bộ nhớ có bao giờ trở nên quan trọng trong điện toán khoa học thực tế / tính toán hiệu năng cao không?

  2. Nếu ở tất cả, làm thế nào để bạn tránh nó? Có thể mô hình máy của tôi thậm chí còn sai và hệ điều hành bằng một số phép thuật nặng nề sẽ sắp xếp lại bộ nhớ một cách ngầm định hoặc quản lý các khối bị phân mảnh trên đống.

  3. Cụ thể hơn, nó ảnh hưởng đến quản lý lưới điện như thế nào?

Câu trả lời:


11

Tôi không đồng ý với Matt về việc sử dụng toàn bộ bộ nhớ cho lưới và về việc bổ sung thêm. Đối với các phương thức tường minh, thông thường một số lượng rất nhỏ các vectơ (ví dụ 2) đại diện cho tất cả các trạng thái mô phỏng. Đối với một vấn đề vô hướng, chỉ cần xác định tọa độ của lưới có thể nhiều hơn mức này và nếu kết nối rõ ràng, thì về cơ bản là nhiều hơn. Mô phỏng độ phân giải cao với các phương thức rõ ràng thường cần một số lượng lớn các bước thời gian, do đó, thông thường sử dụng các tên miền phụ nhỏ hợp lý chỉ để có thể hoàn thành một mô hình chạy trong một khoảng thời gian hợp lý. Vì vậy, nó không phải là tất cả những gì phổ biến để hết bộ nhớ vì chi phí lưu trữ lưới.

Một vấn đề cơ bản hơn nhiều là yêu cầu băng thông bộ nhớ cho mỗi bước của thuật toán (ví dụ: đánh giá phần dư hoặc thực hiện bước thời gian). Đối với các phương pháp phi cấu trúc, điều này liên quan đến một số thông tin dựa trên lưới, nhưng nó thường không yêu cầu truy cập tất cả lưu trữ lưới. Lưu ý rằng ngay cả khi bộ nhớ của bộ giải chiếm ưu thế bộ nhớ lưới (như thường thấy đối với nhiều phương thức ngầm), mô phỏng vẫn thường xuyên phụ thuộc vào yêu cầu băng thông của truyền tải lưới. Có hai yếu tố:

Dữ liệu nào là cần thiết trong quá trình truyền lưới thường xuyên?

Trong các phương pháp phần tử hữu hạn, cần có bản đồ từ phần tử đến toàn cầu. Để cao hơn thứ tự đầu tiên, điều này thường được thực hiện bằng cách liên kết các mức độ tự do với các thực thể trung gian như mặt và cạnh, nhưng một khi bản đồ phần tử đến toàn cầu được xây dựng, các thực thể trung gian không cần thiết. Cụ thể, khả năng kết nối của các thực thể trung gian không bao giờ được sử dụng trực tiếp bởi một mô phỏng. Thông tin đó có thể không được chạm vào trong nhiều lần lặp của bộ giải ẩn hoặc tích hợp thời gian, nhưng vẫn được yêu cầu trong quá trình thích ứng hoặc để thiết lập một không gian chức năng mới. Việc thiết lập bản đồ thành phần toàn cầu trong một mảng đơn giản và không chạm vào cấu trúc dữ liệu "lưới" trong giai đoạn này, trong trường hợp định dạng lưu trữ và vị trí dữ liệu của chính lưới ít quan trọng hơn.

Các phương pháp thể tích hữu hạn đòi hỏi thể tích tế bào, kết nối trực tiếp, diện tích khuôn mặt và quy tắc khuôn mặt. Lưu ý rằng tọa độ đỉnh hoặc kết nối không cần thiết có sẵn. Trong các ví dụ cực đoan (ví dụ FUN3D), tất cả các thông tin khác sẽ bị loại bỏ trong quá trình tiền xử lý ngoại tuyến (tạo lưới) và chỉ có biểu diễn rút gọn này có sẵn cho mô phỏng. Điều này rất hiệu quả, nhưng ngăn chặn các lưới di chuyển và sàng lọc thích ứng.

Làm thế nào là dữ liệu được đặt ra trong bộ nhớ?

Đối với nhiều mô phỏng, với các đơn đặt hàng khiêm tốn về độ chính xác và độ phức tạp của vật lý, hiệu suất bị giới hạn bởi băng thông bộ nhớ. Các kiến ​​trúc CPU hiện đại của IBM, Intel, AMD và NVidia hỗ trợ cường độ số học từ 4 đến 8 flops / byte. Với các đơn vị dấu phẩy động hiệu quả như vậy, chúng ta nên cố gắng tối ưu hóa các thuật toán của mình cho băng thông bộ nhớ. Điều này có thể liên quan đến những thay đổi thuật toán hơi sâu như ưu tiên các phương thức bậc cao chưa được phân tách (so sánh các dòng "tenor" đã lắp ráp và (không tách rời) trong hình thứ hai), nhưng chúng ta có thể bắt đầu bằng cách cố gắng sử dụng đầy đủ băng thông được cung cấp bởi phần cứng. Điều này thường liên quan đến thứ tự tính toán (của đỉnh, mặt, ô, v.v.) sao cho bộ đệm được sử dụng lại tốt nhất có thể. Nó cũng liên quan đến việc khai thác chặn và đặt hàng các ẩn số để có siêu dữ liệu tối thiểu và kích hoạt đúng số lượng luồng dữ liệu. (Thông thường mô phỏng không cấu trúc 3D kết thúc với các luồng "quá nhiều", nhưng một số phần cứng hiện đại như POWER7 cần nhiều luồng để bão hòa băng thông, do đó, đôi khi có ý định tổ chức dữ liệu để kích hoạt nhiều luồng hơn.) Công việc PETSc-FUN3D cung cấp một cách cổ điển , nhưng vẫn thảo luận rất có liên quan về các tối ưu hóa hiệu suất này cho CFD ẩn không cấu trúc.

Gợi ý cho vấn đề của bạn

  1. Đừng sợ malloc(). Không cần phải đóng gói tinh chỉnh hiện tại của lưới vào cùng một mảng với phần không hoạt động của lưới. Bất cứ khi nào bạn không còn cần một phần cũ của lưới, chỉ cần free()nó.

  2. Sau khi tinh chỉnh, tính toán một thứ tự tốt cho mức độ tinh chỉnh đó ( Reverse Cuthill-McKee là phổ biến, nhưng cũng có thể sử dụng các thứ tự cụ thể hơn cho bộ nhớ cache). Nếu sự mất cân bằng tải của bạn là hợp lý (dưới 10%, giả sử), bạn có thể tính toán thứ tự mới này cục bộ (không phân vùng song song và phân phối lại). Chi phí có thể sẽ tương tự như một giao dịch lưới "vật lý" duy nhất, nhưng có thể tăng tốc các giao dịch đó theo hệ số từ 2 trở lên. Bước này thường sẽ trả hết thời gian thích ứng lưới không xảy ra trên mỗi"Vật lý" lưới ngang. Nếu sự thích ứng thường xuyên như vậy là cần thiết cho vấn đề của bạn, bạn có thể thực hiện những thay đổi nhỏ và thỉnh thoảng vẫn nên sắp xếp lại. Tôi vẫn sẽ tránh các nhóm bộ nhớ chi tiết vì nó khiến việc sắp xếp lại khó khăn hơn, nhưng bạn có thể sử dụng các khối lớn hợp lý để cân bằng việc sử dụng bộ nhớ tối đa, chi phí đặt hàng và chi phí cập nhật gia tăng.

  3. Tùy thuộc vào sự rời rạc, hãy xem xét trích xuất một biểu diễn giảm với yêu cầu băng thông bộ nhớ thấp cho các giao dịch "vật lý". Sự gián tiếp không cần thiết là xấu vì nó làm tăng các yêu cầu về băng thông và, nếu mục tiêu của sự gián tiếp không đều, gây ra việc sử dụng lại bộ đệm kém và ức chế việc tìm nạp trước.


Vấn đề này đối với kết nối trung gian chiếm băng thông là không đáng kể để loại bỏ cho trường hợp của bạn và được thực hiện là PETSc DMComplex. Bạn ly dị lưu trữ cấu trúc liên kết lưới từ dữ liệu thực địa. Lưu trữ yếu tố toàn cầu là sai trong mọi trường hợp tôi nghĩ. Cấu trúc liên kết có cùng thông tin trong không gian nhỏ hơn, và phong phú hơn nhiều. Bạn soạn một giao dịch ngang, như đóng, với phần bù vào kho.
Matt Knepley

5

Trong deal.II, chúng tôi tinh chỉnh lưới bằng cách loại bỏ các ô cũ và thay thế chúng bằng các ô mới. Nhưng những cái mới cũng được đặt vào các lỗ nhớ do các ô bị xóa. Tất cả các vòng lặp trên tất cả các ô sau đó được thực hiện theo thứ tự các ô được gặp trong bộ nhớ để giữ cho bộ nhớ cache đạt mức cao.

Câu hỏi lớn hơn là cách bạn lưu trữ dữ liệu xác định các ô. Tất nhiên bạn có thể thực hiện struct Simplex {đỉnh Vertex [4]; int liệu_id; int subomain_id; bool sử dụng; void * user_data; };

lớp Triangulation {Simplex * ô; }; nhưng đây không phải là bộ đệm hiệu quả vì hầu hết các vòng lặp trên tất cả các ô sẽ chỉ chạm vào một tập hợp con dữ liệu bạn lưu trữ trong cấu trúc dữ liệu Simplex của bạn và do đó chỉ một phần dữ liệu rơi vào bộ đệm sẽ thực sự được sử dụng. Một chiến lược tốt hơn là làm một cái gì đó như thế này: đỉnh Triangulation {Vertex *; int * liệu_ids; int * subomain_ids; bool * used_flags; void * * user_data; }; Bởi vì trong các vòng lặp trên tất cả các ô lặp lại có khả năng truy cập vào cùng một tập hợp dữ liệu xác định các ô, bộ đệm đọc trước sẽ chỉ tải trước dữ liệu mà bạn thực sự sẽ sử dụng và do đó sẽ dẫn đến tốc độ truy cập bộ đệm cao.


4

1) Không. Bộ nhớ bộ giải vượt xa bộ nhớ lưới. Ngay cả khi bạn chạy bộ giải nhẹ nhất, rõ ràng, lưới nhiều nhất là 25% bộ nhớ của mô phỏng và nhiều khả năng <10%.

2) Chia nhỏ phân bổ của bạn và sử dụng nhóm bộ nhớ. Bạn không cần phân bổ một đoạn liền kề cho toàn bộ lưới vì bạn thường chỉ cần lặp lại trên các phần cục bộ. Giới thiệu một cấp độ của sự gián tiếp không ảnh hưởng đến hiệu suất một cách có ý nghĩa.


Bất kỳ tài liệu tham khảo cho yêu cầu này? Một phương pháp ma trận miễn phí đơn giản nên có dấu chân của người giải rất nhẹ.
aterrel

2
Chắc chắn, nếu bạn làm ma trận miễn phí, đó có thể là một vấn đề khác. Nhưng nói ngắn gọn là nhận xét của Matt là đúng: với mỗi mức độ tự do trên lưới, ma trận phải lưu trữ nhiều gấp đôi số cặp DoF này - trong tất cả các trường hợp 3d không tầm thường chạy vào hàng trăm (tính số này một lần cho phần tử Q2-Q1 / Taylor-Hood Stokes ở chế độ 3d). Bạn sẽ dễ dàng thấy rằng việc này chiếm nhiều bộ nhớ hơn dữ liệu xác định lưới.
Wolfgang Bangerth

0

Nếu bạn hết bộ nhớ, chỉ cần chạy trên nhiều nút hơn để bạn có nhiều bộ nhớ hơn. Bạn đang lãng phí một nguồn tài nguyên rất quý giá (bộ não con người) để giải quyết vấn đề có giải pháp rất dễ dàng.

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.