2012-08-12 19 views
7

Vì vậy, tôi muốn chuyển đổi trò chơi PC của mình thành Xbox 360. Nó chạy tốt trên PC, với Intel Core 2 Quad @ 2.40Ghz và Radeon 4850 512MB.PC XNA Game được chuyển đổi thành Xbox 360 - Các vấn đề hiệu suất lớn

Tôi đã chuyển nó sang Xbox, và tắt dơi, đã xảy ra một số vấn đề bất thường và kế thừa về việc nhập danh sách, vì vậy tôi chỉ sử dụng phương thức LINQ được gọi là .Cast <>().

Nếu phương pháp đó là phải mất một chi phí lớn, cho tôi biết, vì tôi không thể triển khai Phân tích Hiệu suất trên 360 đối với một số lý do, rất có thể vì nó đóng trên 360.

Sau đó, một vấn đề khác đến, và nó là một System.OutOfMemoryException tốt đẹp. Kết cấu skybox của tôi là 4096x4096, do đó giảm bớt chúng bằng một nửa loại bỏ lỗi đó. Mặc dù vậy, chúng chỉ có 3MB x 6, vì vậy nó không nên sử dụng nhiều dung lượng 512 MB.

Vì vậy, khi tất cả những vấn đề đó đã bị xóa khỏi đường đi, một khung hình đẹp mỗi 2 giây được giới thiệu. Sau đó nó bị treo sau 1 phút chơi game, một "Mã số 4" bất cứ điều gì có nghĩa là.

Nó phát như một powerpoint. Dưới đây là một số hình ảnh phân tích hiệu suất từ ​​lối chơi PC. Họ không phải là xấu.

CPU: http://i.imgur.com/JYx7Z.png RAM: http://i.imgur.com/C29KN.png Và 72% = 150MB cho bạn.

Tôi hy vọng bất kỳ ai ở đây đều có một số kinh nghiệm về vấn đề này. Thành thật mà nói tôi là tất cả tai.

Trả lời

11

Nguyên nhân gốc rễ của sự cố hiệu suất của bạn gần như chắc chắn vì bạn đang cấp phát bộ nhớ trong khi trò chơi của bạn đang chạy (sau khi khởi động, trong vòng lặp Draw/Update).

Trên Windows, điều này là tốt. Bộ thu gom rác trên Windows là thế hệ (sẽ chỉ dọn dẹp các đối tượng mới khi có thể) và cực kỳ nhanh. Đó là thông minh về khi nó chọn để chạy, quá.

Bộ thu gom rác trên Xbox 360, mặt khác, hoàn toàn là rác. Nó chạy cho mỗi 1MB bộ nhớ được cấp phát. Nó kiểm tra toàn bộ vùng được quản lý khi nó chạy. Và nó khá chậm để khởi động.

Vì vậy, câu trả lời là không bao giờ cấp phát bộ nhớ trong khi trò chơi của bạn đang ở trạng thái đang chạy.

Có một bài đăng trên blog tốt về điều này here. (Nó cũng mô tả các thay thế để không bao giờ phân bổ bộ nhớ - đó là để giảm đống phức tạp - đó thực sự là rất khó thực hiện và tôi không khuyên bạn nên nó.)

  • Bạn sẽ phải loại bỏ những thứ như LINQ, như các đối tượng truy vấn mà nó tạo ra là các đối tượng đống, cũng như các đại biểu mà nó thường xuyên yêu cầu. Sử dụng các vòng lặp đơn giản thay thế.
  • Nếu bạn đang phân bổ các loại tham chiếu của riêng bạn trong quá trình vẽ/cập nhật, bạn sẽ phải chuyển đổi sang sử dụng các loại giá trị nếu có thể hoặc thêm nhóm đối tượng.
  • Tạo đối tượng string là một nguồn cấp phát bộ nhớ chung khác - thay vào đó bạn có thể sử dụng lại một số StringBuilder và hiển thị trực tiếp.
  • Chuyển đổi mọi thứ (đặc biệt là: số) thành chuỗi, ngay cả đối với StringBuilder sẽ cấp phát bộ nhớ. Bạn cần viết/tìm các lựa chọn thay thế miễn phí.My answer to this similar question có một cho int.

Cách tốt nhất để chẩn đoán nơi bạn đang phân bổ bộ nhớ để chạy trò chơi của bạn với CLR Profiler trên Windows. Điều này sẽ cho bạn biết vị trí và thời điểm bộ nhớ được cấp phát. Chỉ cần tối ưu hóa cho đến khi bạn không phân bổ.

(Hoặc cho đến khi bạn phân bổ đáng tin cậy dưới 1MB cho mỗi cấp độ/bản đồ/phòng/bất cứ điều gì và thực hiện GC thủ công trong thời gian thích hợp để nói lắp - như màn hình tải tĩnh hoặc mờ dần .)

Mã 4 là Ngoại lệ không được xử lý. Bạn cần phải cài đặt trình xử lý ngoại lệ cấp cao nhất xuất ra một tin nhắn hoặc chạy trò chơi của bạn trong trình gỡ lỗi để xác định nguyên nhân.

Cuối cùng: Đó có thể là kích thước được nén của hoạ tiết của bạn (sử dụng PNG hoặc JPEG hoặc tương tự). Nếu họa tiết của bạn không bị nén, 4096 × 4096 × 6 × 4 bytes = 384MB. Điều này là rất lớn - không có thắc mắc bạn đã hết bộ nhớ. Bạn có thể nén chúng với DXT1 và làm cho chúng nhỏ hơn 6 lần (instructions, wiki). Bạn cũng có thể giảm độ phân giải của chúng. Và bạn có cần mặt dưới cùng?

+1

Cảm ơn một nhóm, sau rất nhiều tìm kiếm tôi đã tìm thấy câu trả lời tương tự cho bạn và khi tôi chạy Hồ sơ CLR, tôi thấy rằng tôi đã phân bổ khoảng 60MB mỗi khung hình ... không tốt. Đó là bởi vì tôi thêm tất cả các đối tượng collidable trong trò chơi của tôi vào một danh sách, và sau đó ném chúng vào một Collision Thread mỗi khung. Tôi có thể biến nó thành một danh sách tĩnh, nơi nó chỉ là một tham chiếu, mà tôi có lẽ sẽ làm, nhưng sau đó tôi giữ khả năng trễ va chạm. Nhưng tôi đoán đó là lựa chọn duy nhất. –