Các mẫu phân bổ bộ nhớ được sử dụng trong phát triển trò chơi


20

Tôi đã nghiên cứu tạo ra các phương thức cấp phát của riêng mình (sẽ hỗ trợ những thứ như nhóm bộ nhớ và định hình), tuy nhiên, khi tôi tiếp tục nghiên cứu, tôi đã tìm kiếm cách thức này được thực hiện trong quá trình phát triển trò chơi.

Tôi có thể sử dụng kỹ thuật phân bổ bộ nhớ nào và tại sao nó là một kỹ thuật tốt?


1
bạn có thực sự cần phải không? đó chỉ là một trong những điều phức tạp nhất mà một nhóm có thể thực hiện, nếu họ có thể thực hiện nó.
Ali1S232

4
Đây là một lĩnh vực mà tôi quan tâm, vì vậy tôi muốn tìm hiểu về nó và thực hiện nó
chadb 18/03 '

Tôi phải nói rằng chủ đề này thực sự thú vị ... Có những trường hợp có thể có nghĩa là phân bổ, nhưng trên trò chơi PC trung bình của bạn, tôi sẽ lo lắng về trò chơi thực tế ...
rioki

Bạn đã nghiên cứu mã nguồn cho malloc thư viện tiêu chuẩn hiện đại và miễn phí hoặc mới và xóa? Tôi hỏi bởi vì dường như điều đó sẽ cung cấp một cơ sở rất hữu ích để so sánh với bất kỳ chiến lược phân bổ thay thế nào so với thuật toán hoặc thực tế. Có vẻ như nó cũng sẽ cung cấp một số hiểu biết thực sự về những gì bạn sẽ nhận được vào.
Louis Langholtz

Câu trả lời:


25

Game Engine Architecture có một số thông tin liên quan đến chủ đề này. Điều cơ bản là bạn cần thực hiện một số phân tích để hiểu yêu cầu bộ nhớ của bạn trên mỗi cấp độ / khung hình / v.v. giống như, nhưng có một vài mẫu mà tác giả đề cập đã thấy nhiều lần:

  • Phân bổ dựa trên ngăn xếp: Chúng phân bổ một phân đoạn bộ nhớ lớn một lần, sau đó phân bổ các con trỏ trong khối bộ nhớ đó để đáp ứng các yêu cầu từ các nơi khác trong trò chơi. Điều này hữu ích để tránh các chuyển đổi ngữ cảnh theo yêu cầu cấp phát bộ nhớ và cũng vì bạn có thể sử dụng các kỹ thuật của riêng mình để thực thi sự liên tục hoặc căn chỉnh cụ thể cho các hoạt động của SIMD. Một số công cụ cũng sử dụng ngăn xếp hai đầu trong đó một loại tài nguyên được tải từ trên xuống và loại khác được tải từ dưới lên. Có lẽ LSR (Tải và ở lại cư trú, loại điều sẽ cần trong toàn bộ trò chơi của bạn) từ đầu và dữ liệu theo cấp độ từ dưới lên.
  • Bộ nhớ khung đơn hoặc bộ nhớ khung đệm đôi: Bộ nhớ cho các hoạt động xảy ra trong một hoặc hai chu kỳ khung. Điều này rất hữu ích vì thay vì phải phân bổ / phân bổ từng khung hình, bạn chỉ cần xóa dữ liệu của khung cuối cùng bằng cách đặt lại con trỏ bạn sử dụng để theo dõi bộ nhớ ở đầu khối.
  • Nhóm đối tượng: Một khối bộ nhớ cho nhiều đối tượng có cùng kích thước, chẳng hạn như các hạt, kẻ thù, đạn. Điều này rất hữu ích vì bạn có thể dễ dàng đạt được sự liên tục bằng cách tìm phân đoạn không sử dụng đầu tiên trong nhóm của bạn. Chúng cũng làm cho việc lặp lại dễ dàng, bởi vì mỗi đối tượng ở một điểm bù đã biết từ cuối cùng.

Điều lớn nhất mà tác giả đề cập đến là tìm kiếm sự phân mảnh bộ nhớ. Đây không phải là vấn đề nếu bạn đang phát triển ví dụ như PC, nơi bạn có một loại sao lưu phân trang bộ nhớ mà bạn có thể tin cậy, nhưng trong bối cảnh bộ nhớ cố định như bảng điều khiển, có nguy cơ bị "hết bộ nhớ" khi cố gắng phân bổ cho một đối tượng lớn vì bộ nhớ của bạn bị phân mảnh theo cách chỉ có các khối liền kề nhỏ. Vì vậy, ông khuyến nghị rằng một bộ cấp phát dựa trên ngăn xếp như trên cũng bao gồm một phương pháp chống phân mảnh định kỳ nội dung của nó.

Để biết thêm thông tin về mã thực tế liên quan đến điều này, tôi đánh giá cao bài viết của Christian Gyrling, "Chúng ta có hết bộ nhớ không?" , bao gồm các kỹ thuật cho các cấp phát tùy chỉnh, chủ yếu từ góc độ phân tích các kiểu sử dụng bộ nhớ, nhưng điều này cũng có thể áp dụng để đưa ra giải pháp tùy chỉnh cho quản lý bộ nhớ.


1

Từ những gì tôi đã thấy (nhưng chưa hoàn thành), mỗi trò chơi có xu hướng kế thừa các cơ chế phân bổ từ một khung, từ một công cụ trò chơi, từ phiên bản trước (2010 -> 2011) hoặc nó có một bộ các cơ chế mới được viết riêng cho nó cấu trúc (khi cấu trúc dữ liệu có thể tái sử dụng và có kích thước cố định hoặc có nhiều loại và kích cỡ thay đổi).

Ngoài ra, chúng tôi có các cấp phát khác nhau cho các tệp / thành phần âm thanh so với các cấp và các đối tượng trò chơi khác trong cùng một dự án. Trong các dự án khác, bộ cấp phát được kế thừa từ các thư viện bên ngoài chỉ dành cho các thành phần được quản lý bởi lib đó.

Việc tối ưu hóa thực sự phụ thuộc vào nhu cầu của bạn. Nhưng thông thường việc phân bổ được thực hiện trước khi vào cảnh trò chơi và sau đó bộ nhớ được sử dụng lại. Một số trò chơi có thể thoát khỏi việc không có phân bổ tùy chỉnh. Nhưng đối với các trò chơi hành động nơi bộ xử lý, bộ nhớ và tài nguyên dữ liệu được ngân sách bạn không đủ khả năng để mất thời gian xử lý trên các phân bổ lớn, bạn không thể lãng phí bộ nhớ cho việc phân mảnh và các vấn đề khác.

Liên quan đến các ví dụ bạn chỉ cần bắt đầu bằng cách xem công cụ trò chơi OGRE 3D, nó có một vài tùy chọn để định cấu hình bộ cấp phát bộ nhớ.


0

Lỗi thường mắc phải là viết các bộ cấp phát của riêng bạn để bạn có thể kiểm soát nhiều hơn bộ nhớ được sử dụng bởi mỗi hệ thống và có nhiều khả năng hiển thị hơn về những gì đang diễn ra. Một cách tốt hơn để đạt được điều này là sử dụng một trình lược tả bộ nhớ. Có rất nhiều trình biên dịch bộ nhớ ngoài đó, trình biên dịch MemPro của tôi là một ví dụ. Đây là một cách hoàn toàn không xâm lấn để theo dõi tất cả việc sử dụng bộ nhớ và bạn có thể tự động chia nhỏ nó thành các hệ thống phụ bằng cách sử dụng các bộ lọc ký tự đại diện. Lý tưởng nhất là giữ cho phân bổ bộ nhớ và theo dõi bộ nhớ của bạn hoàn toàn riêng biệt, chúng có những yêu cầu hoàn toàn khác nhau.

Việc tự ý phân chia bộ nhớ của bạn thành các nhóm thường có thể gây bất lợi vì mỗi nhóm sẽ có một chi phí chung. Cuối cùng, bạn có thể sử dụng nhiều bộ nhớ hơn mức cần thiết mà không thực sự nhận ra nó. Để giảm lãng phí, tốt hơn hết là gộp tất cả mọi thứ lại với nhau, sự chậm chạp sau đó được cả hệ thống chia sẻ.

Các lý do duy nhất để sử dụng bộ cấp phát tùy chỉnh là hiệu suất CPU (chủ yếu là cho sự kết hợp bộ đệm) và để hạn chế phân mảnh. Một ví dụ hoàn hảo về điều này là một hệ thống hạt. Bạn muốn tất cả các hạt tiếp giáp trong bộ nhớ và bạn không muốn tiêu bộ nhớ chính với nhiều phân bổ tồn tại ngắn. Một ví dụ khác để phân vùng là ngôn ngữ kịch bản.

Nếu bạn muốn có một ví dụ về thay thế malloc cho mục đích chung, bạn có thể xem qua bộ cấp phát VMem của tôi . Nó đã được sử dụng trong một số trò chơi AAA được vận chuyển. Nó có các kỹ thuật hạn chế sự phân mảnh và giữ cho dung lượng bộ nhớ thấp, một điều rất quan trọng đối với các game console. Nó cũng rất nhanh dưới sự tranh chấp chủ đề cao. Trang web của tôi có tài liệu phong phú về các kỹ thuật này.

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.