그래픽 리소스를 비동기식으로로드하는 방법 비동기 I / O를

플랫폼에 구애받지 않는다고 생각합시다. 게임의 나머지 부분이 실행되는 동안 그래픽 리소스를로드하고 싶습니다.

원칙적으로 실제 파일을 별도의 스레드 또는 비동기 I / O를 사용하여로드 할 수 있습니다. 그러나 그래픽 객체를 사용하면 GPU에 업로드해야하며 주 스레드에서만 수행 할 수 있습니다.

게임 루프를 다음과 같이 바꿀 수 있습니다.

while true do
    update()
    for each pending resource do
        load resource to gpu
    end
    draw()
end

디스크에서 RAM으로 별도의 스레드로드 자원이있는 동안.

그러나로드 할 큰 리소스가 많은 경우 프레임 마감 시간이 누락되어 결국 프레임이 삭제 될 수 있습니다. 루프를 다음과 같이 변경할 수 있습니다.

while true do
    update()
    if there are pending resources then
        load one resource to gpu
        remove that resource from the pending list
    end
    draw()
end

프레임 당 하나의 리소스 만 효과적으로로드합니다. 그러나로드 할 작은 자원이 많으면 모두로드하는 데 많은 프레임이 필요하며 많은 시간이 낭비됩니다.

최적의로드 시간은 다음과 같습니다.

while true do
    time_start = get_time()
    update()
    while there are pending resources then
        current_time = get_time()
        if (current_time - time_start) + time_to_load(resource) >= 1/60 then
            break
        load one resource to gpu
        remove that resource from the pending list
    end
    draw()
end

이렇게하면 해당 프레임에 대해 시간 내에 리소스를 사용할 수있는 경우에만 리소스를로드합니다. 불행히도, 이것은 주어진 리소스를로드하는데 걸리는 시간을 추정 할 수있는 방법을 필요로합니다.

내가 여기서 무엇을 놓치고 있습니까? 많은 게임이 프레임을 완전히 떨어 뜨리거나 로딩 시간이 너무 길지 않고 완전히 비동기식으로 모든 내용을로드하는 방법은 무엇입니까?



답변

완벽한 세상을 가정하면서 시작합시다. 리소스를로드하는 두 가지 단계가 있습니다. 먼저 스토리지 미디어에서 올바른 형식으로 메모리로 가져오고 두 번째 단계는 메모리 버스를 통해 비디오 메모리로 전송합니다. 이 두 단계 중 어느 것도 실제로 메인 스레드에서 시간을 사용할 필요가 없습니다. I / O 명령을 실행하기 위해 참여하면됩니다. 리소스가 복사되는 동안 CPU와 GPU 모두 다른 작업을 계속할 수 있습니다. 소비되는 유일한 실제 리소스는 메모리 대역폭입니다.

사용자와 하드웨어 사이에 많은 추상화 계층이없는 플랫폼을 사용하는 경우 API가 이러한 개념을 직접 노출 할 수 있습니다. 그러나 PC를 사용하고 있다면 GPU 드라이버와 사용자 사이에 드라이버가있을 수 있습니다. 이 API에 따라 당신은 할 수 있습니다 드라이버가 소유 한 일부 메모리에 텍스처를 복사합니다 “텍스처를 만들”API를 호출 할 가능성이 소유하는 메모리의 지원되지만 텍스처를 만들 수 있습니다. 이 경우 텍스처를 생성하면 고정 된 오버 헤드와 텍스처의 크기에 비례하는 시간이 있습니다. 그 후 드라이버는 무엇이든 할 수 있습니다. 텍스쳐를 VRAM으로 사전에 전송하거나 처음으로 렌더를 시도 할 때까지 텍스쳐 업로드를 방해하지 않을 수 있습니다.

당신은 그것에 대해 무언가를 할 수도 있고하지 않을 수도 있지만 , “텍스처 생성”호출을하는 데 걸리는 시간을 추측 할 수 있습니다 . 물론 하드웨어와 소프트웨어에 따라 모든 숫자가 변경되므로 리버스 엔지니어링에 많은 시간을 할애 할 가치가 없습니다. 그냥 시도해보십시오! “프레임 당 텍스처 수”또는 “프레임 당 텍스처의 총 크기”와 같은 메트릭을 선택하고 할당량 (예 : 프레임 당 4 개의 텍스처)을 선택한 다음 스트레스 테스트를 시작하십시오.

병리학적인 경우, 두 할당량을 동시에 추적해야 할 수도 있습니다 (예 : 프레임 당 4 개의 텍스처 또는 프레임 당 2MB의 텍스처 중 작은 쪽). 그러나 대부분의 텍스처 스트리밍에 대한 실제 요령은 텍스처를 복사하는 데 걸리는 시간이 아니라 제한된 메모리에 맞추려는 텍스처를 파악하는 것 입니다 .

또한, 한 번에 많은 작은 텍스처가 필요한 것처럼 텍스처 생성을위한 병리학 적 사례는 다른 영역의 병리학 적 사례이기도합니다. 텍스처를 복사하는 데 몇 마이크로 초가 걸리는지 걱정하기 전에 간단한 작업 구현을 얻는 것이 좋습니다. 또한 실제 텍스처 적중은 “텍스처 생성”호출에서 CPU 시간으로 발생하는 대신 텍스처를 사용하는 첫 번째 프레임에서 GPU 시간으로 발생할 수 있습니다.