我正在尝试使用 C++ AMP 计算矩阵。我使用宽度和高度为 3000 x 3000 的数组,并重复计算过程 20000 次:
//_height=_width=3000
extent<2> ext(_height,_width);
array<int, 2> GPU_main(ext,gpuDevice.default_view);
array<int, 2> GPU_res(ext,gpuDevice.default_view);
copy(_main, GPU_main);
array_view<int,2> main(GPU_main);
array_view<int,2> res(GPU_res);
res.discard_data();
number=20000;
for(int i=0;i<number;i++)
{
parallel_for_each(e,[=](index<2> idx)restrict(amp)
{
res(idx)=main(idx)+idx[0];//not depend from calculation type
}
array_view<TYPE, 2> temp=res;
res=main;
main=temp;
}
copy(main, _main);
Run Code Online (Sandbox Code Playgroud)
在计算之前,我将矩阵从主机内存复制到 GPU 内存,并创建一个array_view从 0 到 7 的代码行。
之后,我启动一个循环来计算某些操作并重复 20000 次。每次迭代我都会启动一个parallel_for_each使用 C++ AMP 进行计算的循环。
GPU计算速度非常快,但是当我将结果复制到主机时,array _main我发现这个操作需要很多时间,而且我发现如果我number从20000减少到2000,复制的时间也会减少。
为什么会出现这种情况,是同步问题吗?
您的代码(按原样)无法编译,下面是一个固定版本,我认为它具有相同的意图如果您想从计算时间中分离出复制时间,那么最简单的方法就是使用array<>和明确的副本。
int _height, _width;
_height = _width = 3000;
std::vector<int> _main(_height * _width); // host data.
concurrency::extent<2> ext(_height, _width);
// Start timing data copy
concurrency::array<int, 2> GPU_main(ext /* default accelerator */);
concurrency::array<int, 2> GPU_res(ext);
concurrency::array<int, 2> GPU_temp(ext);
concurrency::copy(begin(_main), end(_main), GPU_main);
// Finish timing data copy
int number = 20000;
// Start timing compute
for(int i=0; i < number; ++i)
{
concurrency::parallel_for_each(ext,
[=, &GPU_res, &GPU_main](index<2> idx)restrict(amp)
{
GPU_res(idx) = GPU_main(idx) + idx[0];
});
concurrency::copy(GPU_res, GPU_temp); // Swap arrays on GPU
concurrency::copy(GPU_main, GPU_res);
concurrency::copy(GPU_temp, GPU_main);
}
GPU_main.accelerator_view.wait(); // Wait for compute
// Finish timing compute
// Start timing data copy
concurrency::copy(GPU_main, begin(_main));
// Finish timing data copy
Run Code Online (Sandbox Code Playgroud)
请注意wait()调用强制计算完成。请记住,C++ AMP 命令通常在 GPU 上对工作进行排队,并且仅当您使用wait()显式等待时才保证执行,或者通过在array_view<上调用(例如)synchronize()来隐式等待。 > . 为了更好地了解计时,您应该分别对计算和数据副本进行计时(如上所示)。您可以在这里找到一些基本的计时代码:http://ampbook.codeplex.com/SourceControl/changeset/view/100791#1983676 in Timer.h 在同一文件夹中有一些使用示例。
然而。我不确定我是否真的会以这种方式编写代码,除非我想打破复制和计算时间。对于纯粹存在于 GPU 上的数据使用array<>,对于从 GPU 复制到或从 GPU 复制的数据使用array_view<>要简单得多。
这看起来像下面的代码。
int _height, _width;
_height = _width = 3000;
std::vector<int> _main(_height * _width); // host data.
concurrency::extent<2> ext(_height, _width);
concurrency::array_view<int, 2> _main_av(_main.size(), _main);
concurrency::array<int, 2> GPU_res(ext);
concurrency::array<int, 2> GPU_temp(ext);
concurrency::copy(begin(_main), end(_main), _main_av);
int number = 20000;
// Start timing compute and possibly copy
for(int i=0; i < number; ++i)
{
concurrency::parallel_for_each(ext,
[=, &GPU_res, &_main_av](index<2> idx)restrict(amp)
{
GPU_res(idx) = _main_av(idx) + idx[0];
});
concurrency::copy(GPU_res, GPU_temp); // Swap arrays on GPU
concurrency::copy(_main_av, GPU_res);
concurrency::copy(GPU_temp, _main_av);
}
_main_av.synchronize(); // Will wait for all work to finish
// Finish timing compute & copy
Run Code Online (Sandbox Code Playgroud)
现在只需要在GPU上的数据就声明在GPU上,需要同步的数据也声明在GPU上。更清晰、更少的代码。
您可以通过阅读我关于 C++ AMP 的书来了解更多信息:)
| 归档时间: |
|
| 查看次数: |
3557 次 |
| 最近记录: |