Microsoft представила C++ AMP

На конференции AMD Fusion 11 Developer Summit Герб Саттер (Herb Sutter) анонсировал новую технологию для разработки гетерогенных приложений на языке С++, получившую название C++ Accelerated Massive Parallelism (AMP). Данная технлогия, по заявлению разработчиков Microsoft, позволит использовать возможности параллельного выполнения кода на CPU, так и выполнения кода на GPU.

Основными конкурентами C++ AMP будут такие технологии, как OpenCL и CUDA. Также Саттер в своем выступлении подчеркнул перспективность использования C++ AMP в облачных вычислениях.
 
Данная технология будет выпущена под открытой спецификацией, что позволит другим компаниям разрабатывать свои реализации C++ AMP. При этом Microsoft намерена помогать сторонним организациям в разработке реализаций данной технологии.

Поддержка C++ AMP скоро появится в Microsoft Visual Studio, где помимо всего прочего будет возможно осуществлять отладку и профилирование приложений, использующих GPU. Также c данной IDE будет поставлять библиотека, похожая на С++ STL, но поддерживающая новую технологию AMP.

О разработки собственных реализаций C++ AMP уже заявили AMD и NVIDIA.
 


Примеры использования AMP.

1. Непараллельный вариант функции ссумирования двух массивов на C++:

void AddArrays(int n, int * pA, int * pB, int * pC)
{
    for (int i=0; i<n; i++) {
        pC[i] = pA[i] + pB[i];
    }
}

Та же функция, распараллеленная с применение AMP:

#include <amp.h>
using namespace concurrency;

void AddArrays(int n, int * pA, int * pB, int * pC)
{
    // Обертки одномерных массивов для их использования в GPGPU вычислениях
    array_view<int, 1> a(n, pA);
    array_view<int, 1> b(n, pB);
    array_view<int, 1> sum(n, pC);

    // Выполнить параллельно несколько lambda-функций (одну на поток)
    parallel_for_each (
        sum.grid, /* grid - структура, описывающая параллельные потоки */
        [=](index<1> idx) restrict(direct3d) { 
            /* с помощью idx передается ID потока, в котором запущена lambda-функция */

            /* restrict(direct3d) указывает компилятору проверить, что lambda-код DirectX-совместим */
            sum[idx] = a[idx] + b[idx]; /* переменные, если нужно, копируются на GPGPU-устройство */
        }
    );
}

 2. Непараллельная функция умножения двух матриц:

void MatrixMultiply( vector<float>& C,
            const vector<float>& vA,
            const vector<float>& vB,
            int M, int N, int W )
{
    for (int y = 0; y < M; y++) {
        for (int x = 0; x < N; x++) {
            float sum = 0;
            for (int i = 0; i < W; i++) {
                sum += vA[y * W + i] * vB[i * N + x];
            }
            vC[y * N + x] = sum;
        }
    }
}

Та же функция, распараллеленная с применнием AMP:

#include <amp.h>
using namespace concurrency;

void MatrixMultiply( vector<float>& vC,
            const vector<float>& vA,
            const vector<float>& vB,
            int M, int N, int W )
{
    // Обертки двумерных массивов для их использования в GPGPU вычислениях
    array_view<const float, 2> a(M, W, vA), b(W, N, vB);
    array_view<writeonly<float>, 2> c(M, N, vC);

    parallel_for_each(
        c.grid,
        [=](index<2> idx) restrict(direct3d) {
            float sum = 0;
            for (int i = 0; i < a.extent.x; i++) {
                sum += a(idx.y, i) * b(i, idx.x);
            }
            c[idx] = sum;
        }
    );
}


Ссылки по теме.

  • Подробнее о C++ AMP
  • Видео с конференции
  • Слайды