2012-12-11 4 views
6

Android/OpenGL에서 게임을 작성하고 성능 향상을 위해 각 스레드를 자체 스레드에서 실행하여 OpenGL (렌더링) 논리를 게임 업데이트 논리와 분리하려고합니다. 내가하지 않는Android : 스레드가 병렬로 실행되지 않음

참조 URL :

내가 각 그러나, 자체 스레드에서 실행되는 DDMS에서 추적기에 따르면, 스레드가 여전히 순차적으로 실행 얻을 관리 (세계는 내 게임 업데이트 스레드) 이미지 권한이 있습니다 : http://img849.imageshack.us/img849/9688/capturegff.png

스레드가 코드를 동시에 실행하지 않는 것 같습니다. 다음과 같이 내가 세상 스레드를 초기화 : 나는 두 개의 스레드 사이에 내 자신의 동기화를 구현했습니다

public class World implements Runnable { 

    Thread thread; 

    public World(...) { 
    ... 
     // Initialise the player/ball objects 
     initialiseObjects(); 

     thread = new Thread(this, "World"); 
     thread.start(); 
} 
} 

. 복제 섬에서와 비슷한 접근법을 사용하여 두 개의 렌더링 버퍼가 있습니다. 렌더링 스레드가 다른 버퍼를 읽는 동안 업데이트 스레드가 버퍼 중 하나에 기록하는 것이 이상적입니다. 버퍼에는 렌더러가 각 스프라이트를 그리는 데 필요한 정보가 들어 있습니다. 업데이트 스레드가 버퍼 업데이트를 완료하고 렌더러가 드로잉을 완료하면 버퍼를 스왑하고 프로세스가 반복됩니다. (렌더 스레드에서 유사한 코드) 게임 업데이트 스레드에서 코드에서

:

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 
    } 

난 적이 없지만 위의 코드는, 스레드의 순차적 인 실행으로 이어질 수있는 방법을 볼 수 없습니다 전에 멀티 스레딩을 시도했기 때문에 나는 근본적으로 잘못된 것을하고 있습니다. 게임 속도를 높이려고 시도한 결과 눈에 띄게 느린 속도로 부드럽게 움직였습니다. 스레드가 병렬로 실행되지 않는 이유는 무엇입니까?

업데이트 : 문제는 휴대 전화의 프로세서가 단일 코어였습니다. 인크레더블 S는 듀얼 코어 였지만 단 하나 뿐이라는 것이 확실했습니다. S2에서 시도해 보았고 실제로 스레드를 병렬로 실행했습니다.

그러나 시장에 출시 된 최신 휴대 전화에서만 지원하는 멀티 스레딩의 장점은 무엇입니까? 멀티 쓰레딩을 구현하여 Replica Island가 이전의 단일 코어 전화기에서 어떻게 더 나은 성능을 관리했는지 이해할 수 없습니다. 확실하게 두 번째 코어를 활용하지 않으면 스레드 간 동기화에 추가되는 오버 헤드로 인해 성능이 저하됩니다.

멀티 스레딩은 단일 코어에서 성능을 저하 시키므로 버퍼를 생성 한 후 그리기 스레드로 전달됩니다. 듀얼 코어의 경우 5-10 % 빨라졌지만, 약 500 스프라이트에서 업데이트주기가 버퍼로 인해 인출주기보다 더 오래 걸렸으므로 속도가 제한됩니다. 물론 최적화를 통해 개선 할 수는 있지만 싱글 코어 프로세서를 희생시키면서 멀티 스레딩을 지원할 가치가 있는지에 대한 의문이 생깁니다. 런타임에 멀티 스레딩을 사용할지 여부를 결정하기 위해 휴대 전화의 프로세서를 결정할 수 있습니까?

+0

단일 코어 만 있고 두 작업 모두 CPU가 제한되어 있으면 실제로는 병렬로 실행할 수 없습니다. 또한,이 'while'루프 내부에는 무엇이 있습니까? 그들은 정말로 빈 고리입니까? –

+0

감사합니다. @ David Schwartz - 그게 정말로 문제였습니다. 인크레더블 S는 듀얼 코어 였지만 단 하나 뿐이라는 것이 확실했습니다. S2에서 시도해 보았고 실제로 스레드를 병렬로 실행했습니다. 그러나 시장에 나와있는 최신 휴대 전화에서만 지원하는 멀티 스레딩의 이점은 무엇입니까? 멀티 쓰레딩을 구현하여 Replica Island가 이전의 단일 코어 전화기에서 어떻게 더 나은 성능을 관리했는지 이해할 수 없습니다. 확실하게 두 번째 코어를 활용하지 않으면 스레드 간 동기화에 추가되는 오버 헤드로 인해 성능이 저하됩니다. – awr

+0

작업이 CPU로 제한되지 않으면 멀티 스레딩에 큰 이점이있을 수 있습니다. 한 태스크가 진행을 진행할 수 없다면 (I/O를 기다리고 있기 때문에) 다른 태스크가 진행할 수 있습니다. 그러나 코어가 하나 뿐이고 작업이 CPU 제한이있는 경우 멀티 스레딩이 도움이되지 않습니다. –

답변

3

기술적으로 보면, 1 CPU는 한 번에 하나의 코드 세그먼트 만 실행합니다. OS scheduler은 프로세스/스레드를 밀리 초 단위로 변경하므로 동시에 여러 프로세스를 실행하는 것처럼 보입니다.

스레드가 지금 완료되었다는 것을 런타임에 알리는 방법은 Thread.yield입니다. 상황에 도움이되지 않는 코드에 바쁜 루프가 있습니다. 그것은 CPU가 아무것도하지 않고 바쁘게 유지합니다.

while(otherBuffer.isFinished() == false) 

대신 바쁜 루프의 Loks를 사용해야하거나 초기 성능 향상을 위해 그 동안 루프 내부 Thread.yield를 호출 시도 할 수 있습니다. Btw, semaphore도 있습니다. 이는 생산자 - 소비자 문제에 대한 가장 간단한 해결책입니다. 현재 코드베이스를 유지하려면 버퍼 당 잠금을 사용할 수 있습니다.

0

class Threadcalling implements Runnable 
    { 

     @Override 
     public void run() { 
} 
} 

그래서 당신은 다음과 같이 많은 스레드 클래스를 생성하고 병렬로 호출 할 수 있습니다
Thread t=new Thread(new Threadcalling()); 
        t.start(); 

아래처럼 사용하여 전화를 아래와 같이 클래스로 스레드를 만듭니다. 그것은 어떤 probs도 만들지 않을 것이다. 잘 작동합니다.

관련 문제