Поделиться через


Использование объектов accelerator и accelerator_view

Можно использовать классы accelerator и accelerator_view для определения устройства или эмулятора, на котором будет выполняться код C++ AMP.Система может иметь несколько устройств или эмуляторов, которые отличаются объемом памяти, поддержкой отладки или поддержкой чисел с плавающей запятой двойной точности.C++ Accelerated Massive Parallelism (C++ AMP) предоставляет интерфейсы API, позволяющие просмотреть все доступные ускорители, задать один из них как ускоритель по умолчанию, использовать несколько ускорителей для множественных вызовов parallel_for_each и выполнять специальные задачи отладки.

Использование ускорителя по умолчанию

Среда выполнения C++ AMP выбирает ускоритель по умолчанию, если только не был написан код для выбора конкретного ускорителя.Среда выполнения выбирает ускоритель по умолчанию следующим образом:

  1. Если приложение выполняется в режиме отладки, то выбирается ускоритель, поддерживающий отладку.

  2. В противном случае выбирается ускоритель, который определяется с помощью переменной среды CPPAMP_DEFAULT_ACCELERATOR, если она задана.

  3. В противном случае — неэмулированное устройство.

  4. В противном случае — устройство с наибольшим объемом доступной памяти.

  5. В противном случае — устройство, которое не подсоединено к дисплею.

Можно определить свойства ускорителя по умолчанию путем его создания и просмотра его свойств.В следующем примере кода выводится путь, объем памяти и возможность поддержки чисел с плавающей запятой двойной точности для ускорителя по умолчанию.

void default_properties() {
    accelerator default_acc;
    std::wcout << default_acc.device_path << "\n";
    std::wcout << default_acc.dedicated_memory << "\n";
    std::wcout << (default_acc.supports_double_precision ? 
        "double precision: true" : "double precision: false") << "\n";
}

Hh873132.collapse_all(ru-ru,VS.110).gifПеременная среды 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_double_precision ? 
            "double precision: true" : "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, — ЦП.Нельзя выполнять код на ускорителе ЦП.Чтобы отфильтровать ускоритель ЦП, необходимо сравнить значение свойства device_path ускорителя, возвращаемого accelerator::get_all, со значением accelerator::cpu_accelerator.Дополнительные сведения см. в разделе "Специальные ускорители" в этой статье.

Изменение ускорителя по умолчанию

Можно изменить ускоритель по умолчанию путем вызова метода 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 в вызовы метода parallel_for_each.

  • Можно создать объект array с помощью указанного объекта accelerator.Среда выполнения C++ AMP выберет объект accelerator_view из перехваченного объекта array в лямбда-выражении.

Специальные ускорители

Пути трех специальных ускорителей доступны в виде свойств класса accelerator:

  • Элемент данных accelerator::direct3d_ref: Этот однопоточный ускоритель использует программное обеспечение на ЦП для эмуляции универсальной видеокарты.Он используется по умолчанию для отладки, но он неэффективен в рабочей среде, поскольку он медленнее, чем аппаратные ускорители.Кроме того, он доступен только в DirectX SDK и Windows SDK и вряд ли будет установлен на компьютерах клиентов.Дополнительные сведения см. в разделе Отладка кода GPU.

  • Элемент данных accelerator::direct3d_warp: Этот ускоритель предоставляет резервное решение для выполнения кода C++ AMP на многоядерных ЦП, которые используют набор инструкций Streaming SIMD Extensions (SSE).

  • Элемент данных accelerator::cpu_accelerator: Этот ускоритель можно использовать для установки массивов промежуточного хранения.Он не может выполнять код C++ AMP.Дополнительные сведения см. в сообщении Массивы промежуточного хранения в C++ AMP в блоге Параллельное програмирование в машинном коде.

Взаимодействие

Среда выполнения C++ AMP поддерживает взаимодействие между классом accelerator_view и интерфейсом Direct3D ID3D11Device.Метод create_accelerator_view принимает интерфейс IUnknown и возвращает объект accelerator_view.Метод get_device принимает объект accelerator_view и возвращает интерфейс IUknown.

См. также

Ссылки

Класс accelerator

Класс accelerator_view

Другие ресурсы

C++ AMP (C++ Accelerated Massive Parallelism)

Отладка кода GPU