Tôi đang viết một trò chơi trong Android/OpenGL và đang cố gắng tách logic OpenGL (render) khỏi logic cập nhật trò chơi của mình, bằng cách chạy từng chủ đề riêng để cải thiện hiệu suất.Android: Chủ đề không chạy song song
tôi quản lý để nhận được mỗi chạy trên thread riêng của mình, tuy nhiên theo Tracer trong DDMS, các chủ đề vẫn đang chạy tuần tự (thế giới là trò chơi của tôi cập nhật thread):
Xem url như tôi không có đặc quyền hình ảnh: http://img849.imageshack.us/img849/9688/capturegff.png
Chủ đề dường như không thực thi mã cùng một lúc. Tôi khởi tạo chủ đề thế giới như sau:
public class World implements Runnable {
Thread thread;
public World(...) {
...
// Initialise the player/ball objects
initialiseObjects();
thread = new Thread(this, "World");
thread.start();
}
}
Tôi đã thực hiện đồng bộ hóa riêng giữa hai chủ đề. Sử dụng một cách tiếp cận tương tự như trong Replica Island, tôi có hai bộ đệm render: thread cập nhật (nên lý tưởng) ghi vào một trong các bộ đệm trong khi thread render đang đọc bộ đệm khác. Bộ đệm chứa thông tin cần thiết cho trình kết xuất để vẽ từng ảnh. Một khi các chủ đề cập nhật đã hoàn thành cập nhật bộ đệm của nó và renderer đã hoàn thành bản vẽ, họ trao đổi bộ đệm và quá trình lặp đi lặp lại.
Trong mã từ các chủ đề trò chơi cập nhật (mã tương tự như trong render thread):
currBuffer.write();
player.draw(currBuffer.getNext());
ball.draw(currBuffer.getNext());
if (particleEffect != null) {
particleEffect.draw(currBuffer);
}
currBuffer.finished();
while(otherBuffer.isFinished() == false) {
//otherBuffer is finished once the render thread has finished drawing
}
DrawBuffer tempBuffer = currBuffer;
currBuffer = otherBuffer;
otherBuffer = tempBuffer;
currBuffer.changed();
while(otherBuffer.isChanged() == false) {
//otherBuffer is changed once the render thread has also swapped buffered
}
Tôi không thể nhìn thấy cách mã trên có thể dẫn đến việc thực hiện tuần tự các chủ đề, mặc dù tôi chưa bao giờ cố gắng đa luồng trước khi có thể tôi đang làm một cái gì đó về cơ bản sai. Nỗ lực của tôi để tăng tốc độ trò chơi đã làm cho nó đáng chú ý chậm hơn và kém trơn tru hơn nhiều. Bất kỳ ý tưởng tại sao các chủ đề không chạy song song?
CẬP NHẬT: Vấn đề là bộ xử lý của điện thoại của tôi chỉ là lõi đơn. Tôi chắc chắn rằng Incredible S là lõi kép nhưng than ôi nó chỉ là duy nhất. Tôi đã thử nó trên S2 và nó thực sự chạy các chủ đề song song.
Tuy nhiên, điều gì sau đó là lợi thế của đa luồng nếu chỉ có các điện thoại mới hơn trên thị trường hỗ trợ nó? Tôi không hiểu sao Replica Island quản lý hiệu suất tốt hơn trên các điện thoại lõi đơn cũ hơn bằng cách triển khai đa luồng. Chắc chắn các chi phí bổ sung trong đồng bộ hóa giữa các chủ đề sẽ dẫn đến hiệu suất chậm hơn nếu không có một lõi thứ hai để tận dụng lợi thế của?
Đa luồng dẫn đến hiệu suất chậm hơn trên lõi đơn do phải tạo bộ đệm sau đó được chuyển đến chuỗi vẽ. Trên lõi kép, nó đã được 5-10% nhanh hơn, mặc dù ở khoảng 500 sprites chu kỳ cập nhật mất nhiều thời gian hơn so với chu kỳ vẽ một lần nữa do bộ đệm, do đó hạn chế tốc độ tăng. Rõ ràng với tối ưu hóa, tôi có thể cải thiện điều đó nhưng câu hỏi trở thành liệu nó có đáng để hỗ trợ đa luồng với chi phí của các bộ vi xử lý lõi đơn hay không. Có thể xác định bộ xử lý của điện thoại để xác định xem có nên sử dụng đa luồng hay không khi chạy?
Nếu bạn chỉ có một lõi đơn và cả hai tác vụ đều bị giới hạn CPU, thì chúng thực sự không thể chạy song song. Ngoài ra, những gì bên trong các vòng lặp 'while' này? Chúng thực sự là các vòng rỗng? –
Cảm ơn @ David Schwartz - đó thực sự là vấn đề. Tôi chắc chắn rằng Incredible S là lõi kép nhưng than ôi nó chỉ là duy nhất. Tôi đã thử nó trên S2 và nó thực sự chạy các chủ đề song song. Tuy nhiên, những gì sau đó là lợi thế của đa luồng nếu chỉ có các điện thoại mới hơn trên thị trường hỗ trợ nó? Tôi không hiểu sao Replica Island quản lý hiệu suất tốt hơn trên các điện thoại lõi đơn cũ hơn bằng cách triển khai đa luồng. Chắc chắn các chi phí bổ sung trong đồng bộ hóa giữa các chủ đề sẽ dẫn đến hiệu suất chậm hơn nếu không có một lõi thứ hai để tận dụng lợi thế của? – awr
Nếu các tác vụ không bị giới hạn CPU, có thể có những lợi ích to lớn cho việc đa luồng. Nếu một nhiệm vụ không thể thực hiện tiến trình chuyển tiếp (nói vì nó đang chờ I/O), một tác vụ khác có thể. Tuy nhiên, nếu chỉ có một lõi, và nhiệm vụ của bạn là CPU giới hạn, đa luồng sẽ không giúp đỡ. –