Làm thế nào bạn có thể song song một mô phỏng boids 2D


16

Làm thế nào bạn có thể lập trình mô phỏng 2D boids theo cách nó có thể sử dụng sức mạnh xử lý từ các nguồn khác nhau (cụm, gpu).

ví dụ

Trong ví dụ trên, các hạt không màu di chuyển xung quanh cho đến khi chúng co cụm (màu vàng) và ngừng di chuyển.

Vấn đề là tất cả các thực thể có khả năng tương tác với nhau mặc dù một thực thể ở phía trên bên trái không có khả năng tương tác với một thực thể ở phía dưới bên phải. Nếu tên miền được chia thành các phân khúc khác nhau, nó có thể tăng tốc toàn bộ, nhưng nếu một thực thể muốn chuyển sang phân khúc khác thì có thể có vấn đề.

Hiện tại mô phỏng này hoạt động với 5000 thực thể với tốc độ khung hình tốt, tôi muốn thử điều này với hàng triệu nếu có thể.

Có thể sử dụng cây quad để tối ưu hóa hơn nữa điều này? Bất cứ một đề nghị nào khác?


Bạn đang yêu cầu tối ưu hóa hoặc làm thế nào để song song? Đây là những điều khác nhau.
bummzack

@bummzack Làm thế nào để song song, tôi vừa thêm giải thích, điều đó có giúp gì không?
Sycren

Câu trả lời:


7

Luận văn thạc sĩ Mô phỏng song song các chất lỏng hạt của Mattias Linde có thể cung cấp một số cái nhìn sâu sắc về phân vùng dữ liệu và thuật toán cho mô phỏng quy mô lớn.

Bài báo của ông hướng đến Smoothed-Particle Hydrodynamics , đối với giải pháp ngây thơ có xu hướng sử dụng Spatial Hashing với kích thước xô xung quanh kích thước dấu chân hạt nhân của các hạt trong mô phỏng.

Vì khoảng cách tương tác được kẹp chặt trong các hạt nhân SPH điển hình, việc tối ưu hóa phân vùng như vậy là gần như cần thiết trong việc mở rộng hệ thống.


giấy đẹp, nhưng phần tình cờ về câu hỏi này dường như rất nhiều như câu trả lời @Fxlll.
Ali1S232

Tôi muốn nói rằng phần thực tế của bài báo là cách nó giải quyết các trường hợp cạnh bằng cách giới thiệu một giao thức truyền thông, đó là phần khó, phân vùng quad là khá rõ ràng và do chính nó không giải quyết được vấn đề trường hợp cạnh.
Maik

4

Thuật ngữ tôi học được từ lâu là tốc độ thông tin của một trò chơi.

Nếu tốc độ của các con bo của bạn là 1 và chúng chỉ quan tâm đến hàng xóm của chúng, thì tốc độ của thông tin là 3, tức là, một con nhím cách bạn hai ô vuông có thể nằm trong phạm vi bạn quan tâm trong một khung hình:

1 chuyển động vuông trên mỗi boid trong tương tác (1 + 1) cộng với khoảng cách mà bạn có thể nhận thấy mọi thứ (1) bằng 3.

Với điều này, chúng ta biết rằng chúng ta có thể chia bản đồ thành từng mảnh, có kích thước nhỏ như chúng ta muốn, nhưng với tốc độ thông tin này chồng lên bất kỳ khối lân cận nào.

Tôi sẽ cho rằng bạn cho phép boids của bạn chỉ di chuyển một hình vuông, nhưng họ có thể thấy ba

Nếu bạn muốn chạy một sim song song khổng lồ, bạn chia thành các lưới 10 x10, nhưng chồng lên nhau bởi 5 ô vuông trên mỗi cạnh. Bất cứ khi nào một trong số bạn kết thúc trong khoảng cách thông tin từ cạnh của khối địa phương, bạn nên cập nhật hàng xóm và một khi họ đi qua ranh giới, họ không thuộc về bạn. Nếu một người hàng xóm nói rằng một con nhím mà họ đang điều khiển đã di chuyển vào khối của bạn, bạn phải chiếm lấy AI của nó.

Điều này có nghĩa là giao tiếp được bản địa hóa cho các nhà quản lý khối lân cận và lưu lượng truy cập được giảm đến mức tối thiểu. Càng chạy nhiều công việc, bạn càng có thể sử dụng nhiều CPU để cung cấp năng lượng cho việc mô phỏng, nhưng bạn càng chạy nhiều công việc, chúng càng chồng chéo lên nhau và do đó càng có nhiều thông tin chuyển giữa các công việc / khối khi quá trình mô phỏng diễn ra. Đây là nơi bạn phải mạnh tay và điều chỉnh kích thước khối dựa trên độ phức tạp của AI và phần cứng bạn có sẵn.


hãy tưởng tượng thế giới có lưới 1.000.000x1.000.000 và trên thế giới có 10.000.000 boid, và mỗi boid có thể di chuyển chính xác một ô vuông mỗi lượt, bạn có thể giải thích làm thế nào để kiểm tra xem có boid trong khu phố của người khác không?
Ali1S 232

Tôi đoán rằng chúng tôi có thể chia nó thành 2000 hình vuông 500x500 hoặc lớn hơn. mỗi ô vuông chứa một danh sách các boids cũng như một danh sách các hàng xóm. Nếu một con nhím thoát ra khỏi một hình vuông thì nó sẽ bị xóa khỏi danh sách các con nhím và được thêm vào hình vuông khác. Vấn đề với phương pháp này mà tôi có thể thấy là nếu bạn thêm một cái gì đó với sự đổ xô lớn hơn hình vuông. giải pháp tứ giác sẽ phải năng động, nhưng tôi không chắc nó sẽ đắt đến mức nào
Sycren

@Gajet: bạn chỉ cần kiểm tra các lỗ hổng trong khối của bạn hoặc biên giới được quản lý hàng xóm. Hãy nhớ rằng, đường viền được đảm bảo bởi thiết kế để tính đến khoảng cách bất kỳ thực thể nào có thể di chuyển cộng với khoảng cách mà các thực thể có thể nhìn thấy. @Sycren: đổ xô, mặc dù chúng ta dường như là một thực thể lớn, vẫn chỉ là một hiệu ứng quy mô nhỏ. Một đàn cá không theo trường, chúng theo những người hàng xóm quan sát được.
Richard Fabian

2

Bằng cách đọc quesiton của bạn, có vẻ như bạn có thể tận dụng lợi thế của cây tứ giác, tạo cây tứ giác và chạy mô phỏng cho từng phân đoạn trên một đơn vị xử lý khác nhau. Điều này sẽ khiến việc kiểm tra chỉ xảy ra với các đối tượng gần nhau. nhưng bạn sẽ cần phải đồng bộ hóa các chủ đề của bạn mỗi chu kỳ. Có nghĩa là để chuyển một số trong số các boids từ một nhóm chế biến sang một nhóm khác. nói chung mỗi chu kỳ sẽ bao gồm 3 bước:

  1. Di chuyển tất cả các boids bằng một đơn vị. (có thể dễ dàng xử lý bằng nhiều luồng)
  2. Chỉ định mỗi boid cho một nhóm *. Điều này có nghĩa là bằng cách sử dụng thuật toán O (n), bạn phải chọn loại bo nào có khả năng gây va chạm nhất. Điều này cũng có thể được xử lý bằng cách sử dụng nhiều chủ đề.
  3. Cuối cùng, bạn phải kiểm tra xem hai chiếc thuyền trong cùng một nhóm có va chạm hay không.

* Để tạo nhóm, bạn có thể sử dụng mẫu bên dưới:

nhập mô tả hình ảnh ở đây

lưu ý rằng một số boids có thể là một phần của nhiều nhóm, nhưng mẫu này cho bạn kết quả chính xác hơn. bạn cũng có thể tạo bao nhiêu nhóm tùy thích bằng cách sử dụng mẫu này, đó chỉ là số bạn phải tìm cho số lượng bo và kích thước màn hình, số lượng nhóm tốt nhất bạn cần tạo.

--biên tập--

có một ý tưởng khác về phân đoạn được mô tả trong bài báo @LarsViklund có đường, cách này có ít kiểm tra kép hơn và không cần tăng / giảm số lượng chủ đề giữa các bước:

nhập mô tả hình ảnh ở đây

lưu ý rằng một số khu vực vẫn là một phần của hai nhóm. và chiều rộng của khu vực cả hai nhóm là chính xác 2*maximum speed. Trong trường hợp của bạn nếu boids di chuyển một pixel trên mỗi bước mô phỏng, bạn chỉ cần chia sẻ diện tích chiều rộng 2 pixel giữa mỗi nhóm 2. và có một khu vực nhỏ là một phần của 4 nhóm. nhưng nói chung phương pháp này dễ thực hiện hơn và nhanh hơn rất nhiều nếu được thực hiện đúng. và bằng cách này, không có di chuyển ngược theo cách này, nếu một số đối tượng có thể di chuyển, nó có thể di chuyển không cần kiểm tra thêm.


Nghe có vẻ là một ý tưởng tốt, nhưng trước khi chuyển sang bước 1, tôi sẽ cần phải phát hiện va chạm để xem liệu họ có thể di chuyển được không?
Sycren

Bạn có thể di chuyển chúng sau đó kiểm tra xem có bất kỳ va chạm nào xảy ra ngược lại khi di chuyển (đối với chính xác đó), nếu không để mô phỏng tiếp tục.
Ali1S 232

Cảm ơn, điều đó có ý nghĩa hơn. Ngoài tứ giác, bạn có thể nghĩ ra cách nào khác để phân chia khối lượng công việc không?
Sycren

Như bạn có thể thấy các phân đoạn của tôi không hoàn toàn là một cây tứ giác, nó có thêm một nhóm để tăng độ chính xác, kiểu cây tứ giác dễ xử lý hơn nhiều. Tùy thuộc vào kích thước thế giới, bạn có thể thêm nhiều nhóm hơn có nghĩa là kiểm tra ít hơn trong mỗi chu kỳ. đó là sự đánh đổi giữa mức tiêu thụ memmory và tốc độ tính toán. và nó không nhất thiết phải là một chủ đề cho mỗi nhóm. bạn có thể có một số chủ đề để tính toán nhiều hơn một nhóm. Bạn cũng có thể phân chia một tính toán nhóm giữa hai hoặc nhiều luồng.
Ali1S232

@Gajet nếu tôi hiểu đúng hình ảnh của bạn, sẽ có rất nhiều phép tính kép, vì các khu vực chồng chéo của các nhóm là rất lớn. Cho rằng câu hỏi yêu cầu mô phỏng lên tới hàng triệu điểm, đó sẽ là một sự lãng phí rất lớn.
Maik

2

Tôi đã giải quyết vấn đề này gần đây bằng cách sử dụng một số câu trả lời này làm điểm bắt đầu. Điều hữu ích nhất cần ghi nhớ là boids là một loại mô phỏng cơ thể n đơn giản: mỗi boid là một hạt tác động một lực lên các nước láng giềng.

Tôi thấy giấy Linde khó đọc; Thay vào đó, tôi đề nghị xem xét "Thuật toán song song nhanh cho động lực phân tử tầm ngắn" của SJ Plimpton , mà Linde đã tham khảo. Bài viết của Plimpton dễ đọc và chi tiết hơn với các số liệu tốt hơn:

Tóm lại, các phương pháp phân rã nguyên tử gán một tập hợp con nguyên tử vĩnh viễn cho mỗi bộ xử lý, các phương pháp phân rã lực chỉ định một tập hợp các phép tính lực theo cặp cho mỗi Proc và các phương pháp phân rã không gian gán một vùng con của hộp mô phỏng cho mỗi Proc .

Tôi khuyên bạn nên thử AD. Đó là cách dễ nhất để hiểu và thực hiện. FD rất giống nhau. Dưới đây là mô phỏng cơ thể n của nVidia với CUDA bằng FD, sẽ cung cấp cho bạn một ý tưởng sơ bộ về cách ốp lát và giảm có thể giúp vượt qua hiệu suất nối tiếp mạnh mẽ.

Việc triển khai SD nói chung là tối ưu hóa các kỹ thuật và đòi hỏi một số mức độ vũ đạo để thực hiện. Chúng hầu như luôn luôn nhanh hơn và quy mô tốt hơn.

Điều này là do AD / FD yêu cầu xây dựng một "danh sách hàng xóm" cho mỗi boid. Nếu mọi boid cần biết vị trí của các nước láng giềng thì giao tiếp giữa họ là O ( n ²). Bạn có thể sử dụng danh sách hàng xóm Verlet để giảm kích thước của khu vực mỗi lần kiểm tra, cho phép bạn xây dựng lại danh sách sau mỗi vài dấu thời gian thay vì mỗi bước, nhưng vẫn là O ( n ²). Trong SD, mỗi ô giữ một danh sách lân cận, trong khi ở AD / FD, mọi ô đều có danh sách lân cận. Vì vậy, thay vì mỗi lần giao tiếp với nhau, mọi tế bào đều giao tiếp với nhau. Sự giảm tốc độ trong giao tiếp là nơi tăng tốc độ đến từ.

Thật không may, vấn đề boids phá hoại SD một chút. Có mỗi bộ xử lý theo dõi một tế bào là lợi thế nhất khi các lỗ được phân phối đều trên toàn bộ khu vực. Nhưng bạn muốn boids tụ lại với nhau! Nếu đàn của bạn hoạt động đúng, phần lớn các bộ xử lý của bạn sẽ bỏ đi, trao đổi danh sách trống với nhau và một nhóm nhỏ các tế bào sẽ kết thúc thực hiện các phép tính tương tự AD hoặc FD.

Để giải quyết vấn đề này, bạn có thể điều chỉnh một cách toán học kích thước của các ô (không đổi) để giảm thiểu số lượng ô trống tại bất kỳ thời điểm nào hoặc sử dụng thuật toán Barnes-Hut cho bốn cây. Thuật toán BH cực kỳ mạnh mẽ. Nghịch lý thay, nó cực kỳ khó thực hiện trên các kiến ​​trúc song song. Điều này là do cây BH không đều, do đó các luồng song song sẽ đi qua nó với tốc độ khác nhau, dẫn đến sự phân kỳ của luồng. Salmon và Dubinski đã trình bày các thuật toán chia đệ quy trực giao để phân phối tứ giác đều giữa các bộ xử lý, chúng phải được lặp lại lặp đi lặp lại cho hầu hết các kiến ​​trúc song song.

Như bạn có thể thấy, chúng ta rõ ràng đang ở trong lĩnh vực tối ưu hóa và ma thuật đen vào thời điểm này. Một lần nữa, hãy thử đọc bài viết của Plimpton và xem nó có ý nghĩa gì không.


1

Tôi giả sử bạn là một hệ thống hình xuyến, bạn có thể phân vùng vào không gian để mỗi đơn vị có diện tích phụ.

Ở mỗi bước các hạt được di chuyển, các hạt đi ra khỏi khu vực phụ được gửi đến bộ xử lý có liên quan; một bước giao tiếp sẽ đồng bộ hóa bộ xử lý và bước cuối cùng được thực hiện để xây dựng vị trí các hạt lạ (nếu có).

Ở đây có ba vấn đề ở đây:

  • 1) hình dạng của khu vực phụ:

Người ta có thể chọn hình chữ nhật nhưng hiển thị tỷ lệ Diện tích / chu vi nhỏ so với vòng xoáy. Đường viền càng lớn thì càng có nhiều hạt. Mặc dù các hạt thể hiện tỷ lệ A / p tốt nhất, không thể được sử dụng cho tessname, vì vậy bạn nên sử dụng một số tessname (bán thường xuyên) với tỷ lệ A / p trung bình tốt. Rõ ràng việc tính toán chỉ số tua bằng tọa độ tế bào nên đơn giản vì vậy hãy xem xét điều này trước để thử một tua rất kỳ lạ.

  • 2) thông tin liên lạc:

Tùy thuộc vào loại cơ sở hạ tầng truyền thông nào bạn có, bạn có thể nghĩ cách phân tán thông tin xuyên biên giới giữa các bộ xử lý. Phát sóng so với tái cấu trúc ngang hàng so với truyền thông ngang hàng là tất cả các tùy chọn.

  • 3) Phân bổ tiểu khu vực:

Bạn nên giữ cho công phu của bạn cân bằng vì có sự đồng bộ hóa ở mỗi bước. Bạn có thể chọn phân bổ tĩnh hoặc động các khu vực cho bộ xử lý. Đây không phải là một vấn đề lớn nếu không gian của bạn được bao phủ một cách chắc chắn bởi các hạt hoạt động nhưng tôi tin rằng nó có thể không đúng trong trường hợp này vì các va chạm làm mất tác dụng của các hạt. Thay đổi phân bổ đòi hỏi một bước giao tiếp nặng hơn; một số phím tắt có thể được thực hiện nếu tất cả các bộ xử lý chia sẻ thông tin xuyên biên giới nhưng bạn phải cân nhắc về nó


@Fxlll Tôi không chắc ý của bạn là gì bởi hệ thống hình xuyến, Nó không có hình dạng của một chiếc bánh rán. Bạn có nghĩa là nếu một hạt đi ra phía bên tay phải, nó xuất hiện lại ở bên trái? Nếu không phải như vậy, nếu một hạt chạm vào phía bên tay phải, nó sẽ cố gắng di chuyển theo một hướng khác.
Sycren

@Sycren ok trong trường hợp này, bạn phải xem xét về tua và xử lý khu vực trên rìa theo cách đặc biệt
FxIII

-1

Hãy thử mô phỏng của tôi để tìm manh mối https://github.com/wahabjawed/Boids-Simulation

Tôi đã phát triển điều này trên XNA


Chỉ cần liên kết đến một dự án hoàn chỉnh không phải là một câu trả lời tốt. Người đọc buộc phải đào qua nguồn của bạn cho đến khi họ tìm thấy phần có liên quan đến câu hỏi và sau đó vẫn cần phải hiểu cách giải quyết vấn đề. Bạn có thể vui lòng mô tả bằng tiếng Anh đơn giản về cách bạn đã tiếp cận vấn đề và lợi thế của nó so với các giải pháp được mô tả trong các câu trả lời khác không? Bạn có thể sao chép và dán một số đoạn mã ngắn vào câu trả lời của bạn nếu chúng giúp hiểu mô tả của bạn.
Philipp
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.