在 Windows 应用商店应用程序中使用 C++ AMP
您的 Windows 应用商店 app 可以使用 C++ AMP (C++ 加速的大量并行) 对 GPU (处理单元) 的图像或其他计算快捷键的计算。 但是,C++ AMP 用于处理不提供了 API 直接在 windows 运行时 (WinRT) 类型,因此,WinRT 为 C++ AMP. 不提供包装。 当您使用时 WinRT 输入您的代码包含这些已创建。您必须将它们转换为与 C++ AMP. 兼容的类型。
性能注意事项
如果使用 Visual C++ 组件扩展 (C++/CX) 创建自己的 Windows 应用商店 app,建议您使用连续使用纯旧数据 (POD) 类型存储有关示例,std::vector 或 C 样式数组将使用 C++ AMP. 的数据。 因为将不必执行的,因此可帮助您完成高的性能比使用非 POD 类型或 windows RT 容器。
在 c. c++ AMP 内核,对于此类存储的访问数据,请包装 std::vector 或排列 concurrency::array_view 的存储然后使用数组视图。concurrency::parallel_for_each 循环:
// simple vector addition example
std::vector<int> data0(1024, 1);
std::vector<int> data1(1024, 2);
std::vector<int> data_out(data0.size(), 0);
concurrency::array_view<int, 1> av0(data0.size(), data0);
concurrency::array_view<int, 1> av1(data1.size(), data1);
concurrency::array_view<int, 1> av2(data_out.size(), data2);
av2.discard_data();
concurrency::parallel_for_each(av0.extent, [=](concurrency::index<1> idx) restrict(amp)
{
av2[idx] = av0[idx] + av1[idx];
});
排列 windows 运行时类型
在使用 WinRT API 时,您可能希望使用在使用 ref 关键字或 value 关键字,存储在一个 WinRT 容器例如 Platform::Array<T>^ 或在复杂数据类型 (如选件类或结构中声明的数据的 C++ AMP。 在这些情况下,必须执行一些额外使数据可用于 C++ AMP。
Platform::Array<T>^,其中 T 为 POD 类型
遇到 Platform::Array<T>^ 时,T 是 POD 类型,使用 get 成员函数,可以访问其基础存储:
Platform::Array<float>^ arr; // Assume that this was returned by a WinRT API
concurrency::array_view<float, 1> av(arr->Length, &arr->get(0));
如果 T 不是 POD 类型,请使用下述使用 C++ AMP. 的数据的方法。
窗口运行时类型:ref 选件类和值选件类
C++ AMP 不支持复杂数据类型。 这包括使用 ref 关键字或 value 关键字,声明的非 POD 类型和任何类型。 如果一个不支持的类型用于 restrict(amp) 上下文,编译时错误。
遇到一个不支持的类型时,可以复制其数据有趣的部分。concurrency::array 对象。 除了之外使数据可用于 C++ AMP 使用,这种手动复制方法可以提高最大化数据位置来提高性能,并且,通过确保不会使用该数据不复制到快捷键。 使用 临时数组,可以进一步提高性能,可以 concurrency::array 的特殊形式提供提示。AMP 运行时应为和其他数组之间的常见调用优化该数组在指定的快捷键等它。
// pixel_color.h
ref class pixel_color sealed
{
public:
pixel_color(Platform::String^ color_name, int red, int green, int blue)
{
name = color_name;
r = red;
g = green;
b = blue;
}
property Platform::String^ name;
property int r;
property int g;
..property int b;
};
// Some other file
std::vector<pixel_color^> pixels (256);
for(pixel_color ^pixel : pixels)
{
pixels.push_back(ref new pixel_color("blue", 0, 0, 255));
}
// Create the accelerators
auto cpuAccelerator = concurrency::accelerator(concurrency::accelerator::cpu_accelerator);
auto devAccelerator = concurrency::accelerator(concurrency::accelerator::default_accelerator);
// Create the staging arrays
concurrency::array<float, 1> red_vec(256, cpuAccelerator.default_view, devAccelerator.default_view);
concurrency::array<float, 1> blue_vec(256, cpuAccelerator.default_view, devAccelerator.default_view);
// Extract data from the complex array of structs into staging arrays.
concurrency::parallel_for(0, 256, [&](int i)
{
red_vec[i] = pixels[i]->r;
blue_vec[i] = pixels[i]->b;
});
// Array views are still used to copy data to the accelerator
concurrency::array_view<float, 1> av_red(red_vec);
concurrency::array_view<float, 1> av_blue(blue_vec);
// Change all pixels from blue to red.
concurrency::parallel_for_each(av_red.extent, [=](index<1> idx) restrict(amp)
{
av_red[idx] = 255;
av_blue[idx] = 0;
});