我刚看过这个:
由于Concurrency::completion_future
的功能似乎模仿std::future
我认为我可以做类似的事情,但这个相对简单的例子失败了:
#include <assert.h>
#include <chrono>
#include <iostream>
#include <amp.h>
int main()
{
using namespace Concurrency;
int big = 1000000; // this should take a while to send back to the host
array_view<int> av(big);
parallel_for_each(extent<1>(big), [=](index<1> idx) restrict(amp)
{
av[idx] = idx[0];
});
int i = 0;
completion_future future = av.synchronize_async();
// this should be false; how could it instantly sent back so much data?
bool const gpuFinished = future.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
assert(!gpuFinished); // FAIL! why?
future.wait();
system("pause");
}
为什么断言会失败?
答案 0 :(得分:4)
在OP中观察到的行为是正确的。
array_view<int> av(big)
创建一个没有数据源的array_view ,而av.synchronize_async()
将修改同步到数据源。因此,对于没有数据源的array_view,根据定义,no-op。通过扩展,它也不会强制执行前面的parallel_for_each
。
如果要将数据同步到CPU内存,在这种情况下需要使用av.synchronize_to_async(accelerator(accelerator::cpu_accelerator).default_view)
显式请求。当然,只有在前面的completion_future
和(可选)复制操作完成时,返回的parallel_for_each
才会就绪。
使用后者替换以前的同步调用会使断言成功,请记住,在具有CPU共享内存的系统上,或者在一些罕见的时间内,它仍然可能会失败(按设计)。
答案 1 :(得分:1)
免责声明:我不是AMP的专家。
AFAIK,array_view
本身并不代表任何东西。这只是一个你应该与某事联系在一起的观点。所以你的代码基本上对我没有意义。您在需要同步的CPU上没有任何后端内存。
请尝试以下代码:
#include <assert.h>
#include <chrono>
#include <iostream>
#include <amp.h>
#include <numeric>
int main()
{
using namespace Concurrency;
using namespace std;
int big = 100000000; // this should take a while to send back to the host
vector<int> vec(big);
iota(begin(vec), end(vec), 0);
array_view<int, 1> av(big, vec);
parallel_for_each(Concurrency::extent<1>(big), [=](index<1> idx) restrict(amp)
{
av[idx] = av[idx] * av[idx];
});
int i = 0;
completion_future future = av.synchronize_async();
// this should be false; how could it instantly sent back so much data?
bool const gpuFinished = future.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
assert(!gpuFinished); // FAIL! why?
future.wait();
std::cout << vec[5];
}
这只是对你的修改,按预期工作。