1

我刚读到这个:

获取 std::future 的状态

由于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");
}

为什么这个断言会失败?

4

2 回答 2

4

在 OP 中观察到的行为是正确的。

array_view<int> av(big)创建一个没有数据源的array_view ,同时av.synchronize_async()同步对数据源的修改。因此,对于没有数据源的 array_view,根据定义,它是无操作的。通过扩展,它也不强制执行前面的parallel_for_each.

如果打算将数据同步到 CPU 内存,在这种情况下,需要使用av.synchronize_to_async(accelerator(accelerator::cpu_accelerator).default_view). 当然,completion_future只有在前面的parallel_for_each和(可选的)复制操作完成时,返回的才准备好。

将前一个同步调用替换为后者可以使断言成功,请记住,在具有 CPU 共享内存的系统上或在某些罕见的时间点上,它仍然可能会失败(按设计)。

于 2013-11-18T04:16:55.437 回答
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];
}

这只是对您的修改,可以按预期工作。

于 2013-11-15T08:53:44.737 回答