2012-01-27 21 views
9

Tôi vừa thêm một số mã tốn kém tính toán vào trò chơi Android mà tôi đang phát triển. Mã trong câu hỏi là một tập hợp các thói quen phát hiện va chạm được gọi rất thường xuyên (mỗi lần lặp của vòng lặp trò chơi) và đang thực hiện một số lượng lớn tính toán. Tôi cảm thấy việc thực hiện phát hiện va chạm của tôi được phát triển khá tốt và nhanh như tôi có thể làm trong Java.Để sử dụng JNI, hoặc không sử dụng JNI (hiệu suất Android)

Tôi đã sử dụng Traceview để cấu hình mã và đoạn mã phát hiện va chạm mới này đôi khi không đáng ngạc nhiên đã tăng gấp đôi thời lượng logic trò chơi của tôi. Đó rõ ràng là một mối quan tâm vì đối với một số thiết bị nhất định, hit hiệu suất này có thể khiến trò chơi của tôi không thể phát được ở trạng thái không thể phát được.

Tôi đã cân nhắc các cách khác nhau để tối ưu hóa mã này và tôi tự hỏi nếu bằng cách di chuyển mã vào C++ và truy cập nó bằng JNI, nếu tôi nhận được một số khoản tiết kiệm hiệu năng đáng chú ý?

Câu hỏi trên là mối quan tâm chính của tôi và lý do tôi yêu cầu. Tôi đã xác định rằng hai lý do sau đây sẽ là kết quả tích cực khác từ việc sử dụng JNI. Tuy nhiên, nó không đủ để thuyết phục tôi chuyển mã của tôi sang C++.

  • Điều này sẽ làm cho mã sạch hơn. Vì hầu hết các phát hiện va chạm là một số loại toán học vector, nó sạch hơn nhiều để có thể sử dụng các toán tử quá tải thay vì sử dụng một số lớp vector chi tiết hơn trong Java.

  • Quản lý bộ nhớ sẽ đơn giản hơn. Đơn giản bạn nói? Vâng, đây là một trò chơi để thu gom rác chạy không được hoan nghênh vì GC có thể sẽ hủy hoại hiệu suất của trò chơi của bạn nếu nó liên tục phải gián đoạn để làm sạch. Trong CI không phải lo lắng về bộ thu gom rác, vì vậy tôi có thể tránh tất cả những thứ xấu xí mà tôi làm trong Java với các biến tĩnh tạm thời và chỉ dựa vào bộ nhớ ngăn xếp cũ tốt của C++

Long-winded vì câu hỏi này có thể là, tôi nghĩ rằng tôi đã đề cập đến tất cả các điểm của mình. Với thông tin này, nó có đáng để chuyển mã của tôi từ Java sang C++ và truy cập nó bằng JNI (vì lý do cải thiện hiệu năng) không? Ngoài ra, có cách nào để đo lường hoặc ước tính mức tăng hiệu suất tiềm năng không?

EDIT:

Vì vậy, tôi đã làm điều đó. Các kết quả? Cũng theo quan điểm của TraceView, tốc độ phát hiện va chạm của tôi tăng gấp 6 lần.

Thật không dễ dàng khi đến đó. Ngoài việc phải nhảy JNI, tôi cũng phải thực hiện một số tối ưu hóa mà tôi không mong đợi. Chủ yếu, bằng cách sử dụng một bộ đệm float được phân bổ trực tiếp để truyền dữ liệu từ Java sang native. Nỗ lực ban đầu của tôi chỉ sử dụng một mảng float để giữ dữ liệu được đề cập bởi vì việc chuyển đổi từ Java sang C++ là tự nhiên hơn, nhưng điều đó thực sự chậm chạp. Các bộ đệm trực tiếp hoàn toàn các vấn đề hiệu suất bên bước với sao chép mảng giữa java và bản địa, và để lại cho tôi với một vết sưng 6x.

Ngoài ra, thay vì lăn lớp vectơ của riêng mình, tôi chỉ sử dụng thư viện toán học Eigen. Tôi không chắc chắn có bao nhiêu ảnh hưởng này đã có hiệu suất, nhưng ít nhất, nó đã giúp tôi tiết kiệm thời gian của dev'ing của tôi (ít hiệu quả) lớp vector.

Bài học khác học được là việc ghi nhật ký quá mức không tốt cho hiệu suất (jic không rõ ràng).

Trả lời

4

Không thực sự là một câu trả lời trực tiếp câu hỏi của bạn, nhưng các liên kết sau đây có thể được sử dụng cho bạn:

Trong liên kết thứ hai sau đây được viết:

Mã gốc không nhất thiết phải hiệu quả hơn Java. Đối với một điều, có chi phí liên quan đến quá trình chuyển đổi bản địa Java và JIT không thể tối ưu hóa trên các ranh giới này. Nếu bạn đang phân bổ các tài nguyên gốc (bộ nhớ trên vùng gốc, bộ mô tả tệp hoặc bất kỳ thứ gì), có thể khó sắp xếp bộ sưu tập kịp thời các tài nguyên này. Bạn cũng cần biên dịch mã của mình cho mỗi cấu trúc mà bạn muốn chạy trên (thay vì dựa vào nó có JIT). Bạn thậm chí có thể phải biên dịch nhiều phiên bản cho những gì bạn xem xét cùng kiến ​​trúc: mã gốc được biên dịch cho bộ xử lý ARM trong G1 không thể tận dụng tối đa ARM trong Nexus One và mã được biên dịch cho ARM trong Nexus One sẽ không chạy trên ARM trong G1.

Mã gốc hữu dụng khi bạn có một mã nguồn gốc hiện tại là mà bạn muốn chuyển sang Android, không phải cho các phần "tăng tốc" của ứng dụng Java.

+0

Tôi biết chi phí của các cuộc gọi JNI. Nhưng tất cả những gì tôi biết là nó tồn tại, và tôi không chắc liệu nó có thể phủ nhận hay có thể làm xấu đi bất kỳ lợi ích hiệu suất nào tôi sẽ nhận được từ việc sử dụng mã nguồn gốc. Tuy nhiên, tôi tò mò hơn nửa cuối của đoạn đầu tiên. Nếu tôi sử dụng một số mã gốc, tôi sẽ phải biên dịch nó cho "các kiến ​​trúc khác nhau" tồn tại? Làm thế nào tôi thậm chí sẽ bắt đầu tìm thấy những kiến ​​trúc mà tôi sẽ cần để biên dịch? Sẽ không làm như vậy gây ra lỗi trong ứng dụng của tôi, hoặc nó sẽ không được tối ưu hóa như nó phải? – user8709

+1

Cuối cùng, như tôi đã nghiên cứu chủ đề này nhiều hơn tôi đã xem qua một bài kiểm tra hiệu suất thú vị đã xem xét các imapct của Java/native với số học dấu chấm động/cố định. Lợi ích từ việc sử dụng mã gốc với các tính toán này là một cải tiến tốt. Tôi tìm thấy những điểm chuẩn có liên quan bởi vì mã tôi muốn làm cho bản địa đang làm rất nhiều tính toán điểm nổi. http://www.badlogicgames.com/wordpress/?p=71 chỉnh sửa: Điều này có thể được nhắm mục tiêu nhiều hơn ở thiết bị Android thế hệ đầu tiên. Các thiết bị này đang trở nên ít liên quan hơn mỗi ngày, vì vậy có lẽ bài viết này không liên quan như tôi nghĩ. – user8709

+0

Tôi thành thật không biết về phần "biên dịch cho các kiến ​​trúc khác nhau", vì tôi thường không sử dụng jni. Liên quan đến các hoạt động điểm nổi, liên kết đầu tiên tôi đăng cũng có một phần về các hoạt động điểm động: "Như quy tắc chung, dấu phẩy động nhỏ hơn khoảng 2 lần so với số nguyên trên thiết bị Android. , JIT-less G1 và Nexus One có FPU và JIT (Tất nhiên, sự khác biệt về tốc độ tuyệt đối giữa hai thiết bị này là khoảng 10x cho phép tính số học.) " – Jave

1

Nếu bạn vẫn đang ở một giai đoạn khá phát triển ban đầu trò chơi, bạn có thể xem xét sử dụng một công cụ trò chơi cung cấp một cơ chế phát hiện va chạm tốt, giống như Libgdx mà làm một công việc khá tốt phát hiện va chạm Box2D.

+2

Đó là một gợi ý tốt cho nhiều nhà phát triển. Tôi quyết định viết engine của riêng mình vì hai lý do: nó là 3 chiều (nhiều game engine android chỉ dành cho game 2d), và tôi cũng thấy quá trình thiết kế và phát triển một hệ thống lớn thực sự thú vị. Động cơ khá lớn vào thời điểm này, 10k + dòng mã và ở nhiều nơi được điều hướng theo dữ liệu. Khi tôi đã phát triển xong chức năng cốt lõi, tôi rất có thể sẽ phát hành nó cho những người khác sử dụng. – user8709

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