Google은 흑인 공동체를 위한 인종 간 평등을 진전시키기 위해 노력하고 있습니다. Google에서 어떤 노력을 하고 있는지 확인하세요.

메모리 풀

이 페이지에서는 드라이버와 프레임워크 간에 피연산자 버퍼를 효율적으로 통신하는 데 사용되는 데이터 구조 및 방법에 대해 설명합니다.

모델 컴파일 시 프레임워크는 상수 피연산자의 값을 드라이버에 제공합니다. 상수 피연산자의 수명에 따라 해당 값은 HIDL 벡터 또는 공유 메모리 풀에 있습니다.

  • 수명이 경우 CONSTANT_COPY , 값은에 위치 operandValues 모델 구조 필드. HIDL 벡터의 값은 프로세스 간 통신 (IPC) 중 복사되기 때문에, 이는 일반적으로 스칼라 오퍼랜드로서 소량의 데이터를 유지하기 위해서만 사용된다 (예를 들어,에 활성화 스칼라 ADD ), 예를 들어 작은 텐서 파라미터 ( 의 형상 텐서 RESHAPE ).
  • 수명 인 경우 CONSTANT_REFERENCE , 값은에있는 pools 모델 구조의 필드. IPC 중에는 원시 값을 복사하는 대신 공유 메모리 풀의 핸들만 복제됩니다. 따라서 HIDL 벡터보다 공유 메모리 풀을 사용하여 많은 양의 데이터(예: 컨볼루션의 가중치 매개변수)를 보유하는 것이 더 효율적입니다.

모델 실행 시 프레임워크는 입력 및 출력 피연산자의 버퍼를 드라이버에 제공합니다. HIDL 벡터로 전송될 수 있는 컴파일 시간 상수와 달리 실행의 입력 및 출력 데이터는 항상 메모리 풀 모음을 통해 전달됩니다.

HIDL 데이터 유형 hidl_memory 매핑되지 않은 공유 메모리 풀을 나타내는 컴파일 및 실행에 모두 사용된다. 드라이버는 그것이의 이름에 따라 사용할 수 있도록 그에 따라 메모리를 매핑해야 hidl_memory 데이터 유형입니다. 지원되는 메모리 이름은 다음과 같습니다.

  • ashmem : 안드로이드는 메모리를 공유했다. 자세한 내용은 참조 메모리 .
  • mmap_fd : 공유 메모리를 통해 파일 기술자의 지원 mmap .
  • hardware_buffer_blob : 형식으로 AHardwareBuffer 바탕으로 공유 메모리 AHARDWARE_BUFFER_FORMAT_BLOB . 신경망(NN) HAL 1.2에서 사용 가능. 자세한 내용은 참조 AHardwareBuffer을 .
  • hardware_buffer : 공유 메모리의 형식은 사용하지 않는 일반 AHardwareBuffer의 지원 AHARDWARE_BUFFER_FORMAT_BLOB . 비BLOB 모드 하드웨어 버퍼는 모델 실행에서만 지원됩니다. NN HAL 1.2에서 사용 가능합니다. 자세한 내용은 참조 AHardwareBuffer을 .

NN HAL 1.3부터 ​​NNAPI는 드라이버 관리 버퍼에 할당자 인터페이스를 제공하는 메모리 도메인을 지원합니다. 드라이버 관리 버퍼는 실행 입력 또는 출력으로도 사용할 수 있습니다. 자세한 내용은 참조 메모리 영역을 .

NNAPI 드라이버의 매핑을 지원해야 ashmemmmap_fd 메모리 이름을. NN HAL 1.3에서 드라이버는 매핑 지원해야 hardware_buffer_blob . 일반적으로 비 BLOB 모드 지원 hardware_buffer 및 메모리 영역은 선택 사항입니다.

A하드웨어버퍼

AHardwareBuffer는 래핑 공유 메모리의 일종 Gralloc 버퍼 . 안드로이드 (10)에, 신경 네트워크 API (NNAPI) 지원 사용하여 AHardwareBuffer를 드라이버가 애플 리케이션을위한 성능과 전력 소비를 개선 복사 데이터없이 실행을 수행 할 수 있도록. 예를 들어 카메라 HAL 스택은 카메라 NDK 및 미디어 NDK API에서 생성된 AHardwareBuffer 핸들을 사용하여 기계 학습 워크로드를 위한 NNAPI에 AHardwareBuffer 객체를 전달할 수 있습니다. 자세한 내용은 ANeuralNetworksMemory_createFromAHardwareBuffer .

AHardwareBuffer이 NNAPI에 사용되는 개체는 통해 운전자에게 전달되는 hidl_memory 중 하나라는 구조체 hardware_buffer 또는 hardware_buffer_blob . hidl_memory 구조체 hardware_buffer_blob 만 AHardwareBuffer 개체를 나타냅니다 AHARDWAREBUFFER_FORMAT_BLOB 형식을.

프레임 워크에 의해 필요한 정보가 인코딩되어 hidl_handle 의 필드 hidl_memory 구조체. hidl_handle 필드는 랩 native_handle AHardwareBuffer 또는 Gralloc 버퍼에 대한 필요한 모든 메타 데이터를 인코딩한다.

드라이버가 제대로 제공 디코딩해야 hidl_handle 메모리는 설명 필드 및 액세스 hidl_handle . 때 getSupportedOperations_1_2 , getSupportedOperations_1_1 또는 getSupportedOperations 메소드가 호출 될 때, 드라이버는 제공된 디코딩 할 수 있는지 여부를 검출한다 hidl_handle 상기 메모리에 액세스하여 설명 hidl_handle . 경우 모델 준비에 실패합니다 hidl_handle 상수 피연산자에 사용되는 필드가 지원되지 않습니다. 경우 생성 실행은 실패한다 hidl_handle 실행의 입출력 연산에 사용되는 필드는 지원되지 않는다. 그것은 반환하는 드라이버를 권장 GENERAL_FAILURE 모델 준비 또는 실행이 실패한 경우 오류 코드를.

메모리 도메인

Android 11 이상을 실행하는 기기의 경우 NNAPI는 드라이버 관리 버퍼에 할당자 인터페이스를 제공하는 메모리 도메인을 지원합니다. 이를 통해 실행 간에 장치 기본 메모리를 전달할 수 있으므로 동일한 드라이버에서 연속 실행 간에 불필요한 데이터 복사 및 변환이 억제됩니다. 이 흐름은 그림 1에 나와 있습니다.

메모리 도메인이 있거나 없는 버퍼 데이터 흐름
도 1의 버퍼 메모리의 데이터 영역을 사용하여 흐름

메모리 도메인 기능은 대부분 드라이버 내부에 있고 클라이언트 측에서 자주 액세스할 필요가 없는 텐서를 위한 것입니다. 이러한 텐서의 예로는 시퀀스 모델의 상태 텐서가 있습니다. 클라이언트 측에서 빈번한 CPU 액세스가 필요한 텐서의 경우 공유 메모리 풀을 사용하는 것이 좋습니다.

메모리 도메인 기능을 지원하기 위해 구현 IDevice::allocate 드라이버 관리 버퍼 할당에 대한 요청에 대한 프레임 워크를 할 수 있도록. 할당하는 동안 프레임워크는 버퍼에 대해 다음 속성과 사용 패턴을 제공합니다.

  • BufferDesc 버퍼의 요구되는 특성을 설명한다.
  • BufferRole 준비된 모델의 입력 또는 출력 버퍼로의 잠재적 사용 패턴을 설명한다. 버퍼 할당 시 여러 역할을 지정할 수 있으며 할당된 버퍼는 지정된 역할로만 사용할 수 있습니다.

할당된 버퍼는 드라이버 내부에 있습니다. 드라이버는 버퍼 위치나 데이터 레이아웃을 선택할 수 있습니다. 버퍼가 성공적으로 할당되면, 운전자의 클라이언트는 반환 된 토큰 또는 사용 버퍼와 상호 작용할 수 또는 참조 IBuffer 개체.

발 토큰 IDevice::allocate 의 하나로서 버퍼를 참조하는 경우에 제공되는 MemoryPool 의 오브젝트 Request 실행의 구조. 프로세스가 다른 프로세스에 할당된 버퍼에 액세스하려는 시도를 방지하려면 드라이버가 버퍼를 사용할 때마다 적절한 유효성 검사를 적용해야 합니다. 드라이버는 버퍼 사용량이 중 하나입니다 확인해야 BufferRole 할당 동안 제공 역할과 사용이 불법 인 경우 즉시 실행을 실패해야합니다.

IBuffer 객체는 명시 적 메모리 복사에 사용됩니다. 특정 상황에서 드라이버의 클라이언트는 공유 메모리 풀에서 드라이버 관리 버퍼를 초기화하거나 버퍼를 공유 메모리 풀로 복사해야 합니다. 사용 사례의 예는 다음과 같습니다.

  • 상태 텐서 초기화
  • 중간 결과 캐싱
  • CPU에서 대체 실행

이러한 사용 사례를 지원하기 위해 드라이버가 구현해야 IBuffer::copyToIBuffer::copyFrom 함께 ashmem , mmap_fdhardware_buffer_blob 는 메모리 영역 할당을 지원하는 경우. 드라이버가 아닌 BLOB 모드를 지원하는 것은 선택 사항입니다 hardware_buffer .

버퍼 할당시, 버퍼의 사이즈에 의해 지정된 모든 역할 대응 기종 피연산자로부터 추론 될 수 BufferRole 및 제공된 치수 BufferDesc . 모든 차원 정보가 결합되면 버퍼에 알 수 없는 차원이나 순위가 있을 수 있습니다. 이 경우 버퍼는 모델 입력으로 사용할 때 치수가 고정된 유연한 상태이고 모델 출력으로 사용할 때 동적 상태입니다. 동일한 버퍼를 다른 실행에서 다른 모양의 출력과 함께 사용할 수 있으며 드라이버는 버퍼 크기 조정을 적절하게 처리해야 합니다.

메모리 도메인은 선택적 기능입니다. 드라이버는 여러 가지 이유로 지정된 할당 요청을 지원할 수 없다고 결정할 수 있습니다. 예를 들어:

  • 요청된 버퍼의 크기가 동적입니다.
  • 드라이버에 큰 버퍼를 처리할 수 없도록 하는 메모리 제약 조건이 있습니다.

여러 다른 스레드가 드라이버 관리 버퍼에서 동시에 읽을 수 있습니다. 쓰기 또는 읽기/쓰기를 위해 버퍼에 동시에 액세스하는 것은 정의되지 않지만 드라이버 서비스가 충돌하거나 호출자를 무기한 차단해서는 안 됩니다. 드라이버는 오류를 반환하거나 버퍼의 내용을 불확실한 상태로 둘 수 있습니다.