다음을 통해 공유


액셀러레이터 및 accelerator_view 개체 사용

액셀러레이터accelerator_view 클래스를 사용하여 C++ AMP 코드를 실행할 디바이스 또는 에뮬레이터를 지정할 수 있습니다. 시스템에는 메모리 양, 공유 메모리 지원, 디버깅 지원 또는 배정밀도 지원에 따라 다른 여러 디바이스 또는 에뮬레이터가 있을 수 있습니다. C++ AMP(C++ 가속 병렬 처리)는 사용 가능한 가속기를 검사하고, 기본값으로 설정하고, parallel_for_each 대한 여러 호출에 대해 여러 accelerator_views 지정하고, 특수 디버깅 작업을 수행하는 데 사용할 수 있는 API를 제공합니다.

메모

C++ AMP 헤더는 Visual Studio 2022 버전 17.0부터 더 이상 사용되지 않습니다. AMP 헤더를 포함하면 빌드 오류가 생성됩니다. 경고를 무음으로 표시하기 위해 AMP 헤더를 포함하기 전에 정의 _SILENCE_AMP_DEPRECATION_WARNINGS 합니다.

기본 가속기 사용

C++ AMP 런타임은 특정 가속기를 선택하는 코드를 작성하지 않는 한 기본 가속기를 선택합니다. 런타임은 다음과 같이 기본 가속기를 선택합니다.

  1. 앱이 디버그 모드에서 실행되는 경우 디버깅을 지원하는 가속기입니다.

  2. 그렇지 않으면 환경 변수에 의해 CPPAMP_DEFAULT_ACCELERATOR 지정된 가속기(설정된 경우)입니다.

  3. 그렇지 않으면 에뮬레이트되지 않은 디바이스입니다.

  4. 그렇지 않으면 사용 가능한 메모리가 가장 많은 디바이스입니다.

  5. 그렇지 않으면 디스플레이에 연결되지 않은 디바이스입니다.

또한 런타임은 기본 가속기에 대해 access_typeaccess_type_auto을 지정합니다. 즉, 기본 가속기는 지원되는 경우 공유 메모리를 사용하고 성능 특성(대역폭 및 대기 시간)이 전용(비공유) 메모리와 동일한 것으로 알려진 경우 공유 메모리를 사용합니다.

기본 가속기를 생성하고 해당 속성을 검사하여 기본 가속기의 속성을 확인할 수 있습니다. 다음 코드 예제에서는 경로, 액셀러레이터 메모리 양, 공유 메모리 지원, 배정밀도 지원 및 기본 가속기의 제한된 배정밀도 지원을 인쇄합니다.

void default_properties() {
    accelerator default_acc;
    std::wcout << default_acc.device_path << "\n";
    std::wcout << default_acc.dedicated_memory << "\n";
    std::wcout << (accs[i].supports_cpu_shared_memory ?
        "CPU shared memory: true" : "CPU shared memory: false") << "\n";
    std::wcout << (accs[i].supports_double_precision ?
        "double precision: true" : "double precision: false") << "\n";
    std::wcout << (accs[i].supports_limited_double_precision ?
        "limited double precision: true" : "limited double precision: false") << "\n";
}

CPPAMP_DEFAULT_ACCELERATOR 환경 변수

기본 가속기를 지정할 수 있도록 환경 변수를 CPPAMP_DEFAULT_ACCELERATOR 설정하십시오 accelerator::device_path. 경로는 하드웨어에 따라 다릅니다. 다음 코드는 함수를 accelerator::get_all 사용하여 사용 가능한 가속기 목록을 검색한 다음 각 액셀러레이터의 경로와 특성을 표시합니다.

void list_all_accelerators()
{
    std::vector<accelerator> accs = accelerator::get_all();

    for (int i = 0; i <accs.size(); i++) {
        std::wcout << accs[i].device_path << "\n";
        std::wcout << accs[i].dedicated_memory << "\n";
        std::wcout << (accs[i].supports_cpu_shared_memory ?
            "CPU shared memory: true" : "CPU shared memory: false") << "\n";
        std::wcout << (accs[i].supports_double_precision ?
            "double precision: true" : "double precision: false") << "\n";
        std::wcout << (accs[i].supports_limited_double_precision ?
            "limited double precision: true" : "limited double precision: false") << "\n";
    }
}

액셀러레이터 선택

가속기를 선택하려면 메서드 accelerator::get_all를 사용하여 사용 가능한 가속기 목록을 검색한 다음 해당 속성에 따라 하나를 선택합니다. 이 예제에서는 메모리가 가장 많은 액셀러레이터를 선택하는 방법을 보여줍니다.

void pick_with_most_memory()
{
    std::vector<accelerator> accs = accelerator::get_all();
    accelerator acc_chosen = accs[0];

    for (int i = 0; i <accs.size(); i++) {
        if (accs[i].dedicated_memory> acc_chosen.dedicated_memory) {
            acc_chosen = accs[i];
        }
    }

    std::wcout << "The accelerator with the most memory is "
        << acc_chosen.device_path << "\n"
        << acc_chosen.dedicated_memory << ".\n";
}

메모

반환되는 가속기 중 하나는 accelerator::get_all에서 제공하는 CPU 가속기입니다. CPU 가속기에서 코드를 실행할 수 없습니다. CPU 가속기를 제거하려면, accelerator::get_all에 의해 반환된 가속기의 device_path 속성 값을 accelerator::cpu_accelerator 값과 비교하십시오. 자세한 내용은 이 문서의 "특수 가속기" 섹션을 참조하세요.

공유 메모리

공유 메모리는 CPU와 가속기 모두에서 액세스할 수 있는 메모리입니다. 공유 메모리를 사용하면 CPU와 가속기 간에 데이터를 복사하는 오버헤드가 제거되거나 크게 줄어듭니다. 메모리는 공유되지만 CPU와 가속기 둘 다에서 동시에 액세스할 수 없으므로 정의되지 않은 동작이 발생합니다. 가속기 속성 supports_cpu_shared_memory는 가속기가 공유 메모리를 지원하는 경우 true를 반환하며, default_cpu_access_type 속성은 accelerator에 할당된 메모리의 기본 access_type을 가져옵니다. 예를 들어, 배열과 연결된 accelerator 또는 array_view에서 액세스되는 개체는 accelerator입니다.

C++ AMP 런타임은 각각access_type에 대해 최상의 기본값 accelerator 을 자동으로 선택하지만, CPU에서 읽거나 CPU에서 쓸 때 공유 메모리의 성능 특성(대역폭 및 대기 시간)이 전용(공유되지 않은) 가속기 메모리보다 더 나빠질 수 있습니다. 공유 메모리가 CPU에서 읽고 쓰기 위한 전용 메모리와 함께 수행되는 경우 런타임은 기본값 access_type_read_write으로 설정됩니다. 그렇지 않으면 런타임은 보다 보수적인 기본값 access_type을 선택하고 계산 커널의 메모리 액세스 패턴이 다른 access_type이점을 얻을 경우 앱이 이를 재정의할 수 있도록 합니다.

다음 코드 예제에서는 기본 가속기가 공유 메모리를 지원하는지 여부를 확인한 후, 기본 접근 유형을 재정의하고 이를 사용하여 accelerator_view을 생성하는 방법을 보여 줍니다.

#include <amp.h>
#include <iostream>

using namespace Concurrency;

int main()
{
    accelerator acc = accelerator(accelerator::default_accelerator);

    // Early out if the default accelerator doesn't support shared memory.
    if (!acc.supports_cpu_shared_memory)
    {
        std::cout << "The default accelerator does not support shared memory" << std::endl;
        return 1;
    }

    // Override the default CPU access type.
    acc.set_default_cpu_access_type(access_type_read_write);

    // Create an accelerator_view from the default accelerator. The
    // accelerator_view reflects the default_cpu_access_type of the
    // accelerator it's associated with.
    accelerator_view acc_v = acc.default_view;
}

항상 연결된 acceleratordefault_cpu_access_type을 반영하며, 이를 재정의하거나 변경할 수 있는 인터페이스를 제공하지 않습니다.

기본 가속기 변경

메서드를 호출하여 기본 가속기를 accelerator::set_default 변경할 수 있습니다. 앱 실행당 한 번만 기본 가속기를 변경할 수 있으며 GPU에서 코드를 실행하기 전에 변경해야 합니다. 가속기를 변경하는 후속 함수 호출은 false를 반환합니다. 호출에서 다른 액셀러레이터를 parallel_for_each사용하려면 이 문서의 "다중 가속기 사용" 섹션을 읽어보세요. 다음 코드 예제에서는 기본 가속기를 에뮬레이트되지 않고 디스플레이에 연결되지 않은 가속기로 설정하고 배정밀도를 지원합니다.

bool pick_accelerator()
{
    std::vector<accelerator> accs = accelerator::get_all();
    accelerator chosen_one;

    auto result = std::find_if(accs.begin(), accs.end(),
        [] (const accelerator& acc) {
            return !acc.is_emulated &&
                acc.supports_double_precision &&
                !acc.has_display;
        });

    if (result != accs.end()) {
        chosen_one = *(result);
    }

    std::wcout <<chosen_one.description <<std::endl;
    bool success = accelerator::set_default(chosen_one.device_path);
    return success;
}

여러 가속기 사용

앱에서 여러 가속기를 사용하는 방법에는 두 가지가 있습니다.

  • 객체를 accelerator_view 메서드 호출에 전달할 수 있습니다.

  • 특정 개체를 사용하여 accelerator_view 개체를 생성할 수 있습니다. C++ AMP 런타임은 람다 식의 캡처된 accelerator_view 개체에서 개체를 선택합니다.

특수 가속기

세 개의 특수 가속기의 디바이스 경로는 클래스의 accelerator 속성으로 사용할 수 있습니다.

  • accelerator::direct3d_ref 데이터 멤버: 이 단일 스레드용 가속기는 CPU 상의 소프트웨어로 일반 그래픽 카드를 에뮬레이트합니다. 디버깅에 기본적으로 사용되지만 하드웨어 가속기보다 느리기 때문에 프로덕션 환경에서는 유용하지 않습니다. 또한 DirectX SDK 및 Windows SDK에서만 사용할 수 있으며 고객의 컴퓨터에 설치될 가능성은 낮습니다. 자세한 내용은 GPU 코드 디버깅을 참조하세요.

  • accelerator::direct3d_warp 데이터 멤버: 이 가속기는 스트리밍 SIMD 확장(SSE)을 사용하는 다중 코어 CPU에서 C++ AMP 코드를 실행하기 위한 대체 솔루션을 제공합니다.

  • accelerator::cpu_accelerator 데이터 멤버: 이 가속기를 사용하여 준비 배열을 설정할 수 있습니다. C++ AMP 코드를 실행할 수 없습니다. 자세한 내용은 네이티브 코드 병렬 프로그래밍 블로그의 C++ AMP에서의 Staging Arrays 게시물을 참조하세요.

상호 운용성

C++ AMP 런타임은 클래스와 Direct3D accelerator_view 간의 상호 운용성을 지원합니다. create_accelerator_view 메서드는 인터페이스를 IUnknown 사용하고 개체를 accelerator_view 반환합니다. get_device 메서드는 개체를 accelerator_view 사용하고 인터페이스를 반환합니다IUnknown.

참고하십시오

C++ AMP(C++ Accelerated Massive Parallelism)
GPU 코드 디버깅
accelerator_view 클래스