Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C++;放大器? 我试图用C++ AMP计算斐波那契,每个数字将取决于它的前两个。所以代码是这样的: for (int i = 0; i < size; i++){ a[i] = 0; if (i == 0 || i == 1) a[i] = 1; } array_view<int, 1> A(size, a); parallel_for_each( A.extent, [=](index<1> idx)restrict(amp){ if( A[idx] == 0 ){ while (A[idx - 2] == 0); while (A[idx - 1] == 0); A[idx] = A[idx - 1] + A[idx - 2]; } });_C++_C++ Amp - Fatal编程技术网

如何在C++;放大器? 我试图用C++ AMP计算斐波那契,每个数字将取决于它的前两个。所以代码是这样的: for (int i = 0; i < size; i++){ a[i] = 0; if (i == 0 || i == 1) a[i] = 1; } array_view<int, 1> A(size, a); parallel_for_each( A.extent, [=](index<1> idx)restrict(amp){ if( A[idx] == 0 ){ while (A[idx - 2] == 0); while (A[idx - 1] == 0); A[idx] = A[idx - 1] + A[idx - 2]; } });

如何在C++;放大器? 我试图用C++ AMP计算斐波那契,每个数字将取决于它的前两个。所以代码是这样的: for (int i = 0; i < size; i++){ a[i] = 0; if (i == 0 || i == 1) a[i] = 1; } array_view<int, 1> A(size, a); parallel_for_each( A.extent, [=](index<1> idx)restrict(amp){ if( A[idx] == 0 ){ while (A[idx - 2] == 0); while (A[idx - 1] == 0); A[idx] = A[idx - 1] + A[idx - 2]; } });,c++,c++-amp,C++,C++ Amp,它不会被设置为非零数,因此所有跟随的线程都将被卡在循环中 有什么出路吗?正如上面的评论员所指出的那样,斐波那契是在GPU上进行并行化最差的候选方案之一。在这里,您最好希望使用同步原语来执行一个又一个操作,并序列化所有线程 C++运行时不保证它在GPU上调度线程瓦片的顺序。假设它决定先计算系列的上半部分来安排互动程序?较低的将永远不会运行,内核将挂起。在C++的AMP中没有等价的 WAITE()/CUT>,所以线程不会阻塞运行时没有指示它应该交换阻塞的线程/瓦片并运行其他的。实际上,您使用的是w

它不会被设置为非零数,因此所有跟随的线程都将被卡在循环中


有什么出路吗?

正如上面的评论员所指出的那样,斐波那契是在GPU上进行并行化最差的候选方案之一。在这里,您最好希望使用同步原语来执行一个又一个操作,并序列化所有线程

C++运行时不保证它在GPU上调度线程瓦片的顺序。假设它决定先计算系列的上半部分来安排互动程序?较低的将永远不会运行,内核将挂起。在C++的AMP中没有等价的<代码> WAITE()/CUT>,所以线程不会阻塞运行时没有指示它应该交换阻塞的线程/瓦片并运行其他的。实际上,您使用的是

while
来替代
wait
。这在CPU或GPU上都不是一个好主意,因为在内存同时读写时引入了竞争条件

但是,在一般线程同步的上下文中,您的问题是有效的。用C++ AMP基本上有两种机制;障碍和原子操作

以下示例显示如何使用原子来计算
数据
数组中大于0.999的随机数。数组是用0.0到1.0之间的随机数初始化的,所以这个数字非常小。这意味着在原子操作上阻塞的成本很少发生

array_view<float, 1> theDataView(int(theData.size()), theData);
int exceptionalOccurrences = 0;
array_view<int> count(1, &exceptionalOccurrences);
parallel_for_each(theDataView.extent, [=] (index<1> idx) restrict(amp)
{
    if (theDataView[idx] >= 0.999f) // Exceptional occurrence.
    {
        atomic_fetch_inc(&count(0));
    }
    theDataView[idx] = // Update the value...
});
count.synchronize();
array\u查看数据视图(int(theData.size()),theData);
int ExceptionalOccessions=0;
数组\视图计数(1,&异常出现次数);
每个(Data View.extent,[=](索引idx)限制(amp)的并行\u
{
如果(数据视图[idx]>=0.999f)//异常发生。
{
原子获取公司(&count(0));
}
数据视图[idx]=//更新值。。。
});
count.synchronize();
虽然这说明了如何使用原子,但使用(映射和)还原操作来完全避免使用原子是解决此问题的更有效的方法

下面的示例使用屏障来同步磁贴内线程之间的内存访问。屏障前的前半段代码使用所有线程将数据加载到tile_静态内存中,然后使用屏障使所有线程在访问数据之前等待所有数据加载完毕

array<float, 2> inData(1000, 1000);
array<float, 2> outData(1000, 1000);

parallel_for_each(view, 
    inData.extent.tile<tileSize, tileSize>(), [=, &inData, &outData]
    (tiled_index<tileSize, tileSize> tidx) restrict(amp)
    { 
        tile_static float localData[tileSize][tileSize];
        localData[tidx.local[1]][tidx.local[0]] = inData[tidx.global];

        tidx.barrier.wait();
        index<2> outIdx(index<2>(tidx.tile_origin[1], 
                        tidx.tile_origin[0]) + tidx.local);
        outData[outIdx] = localData[tidx.local[0]][tidx.local[1]];
    });
数组inData(10001000);
阵列输出数据(10001000);
每个视图的平行视图(视图,
inData.extent.tile(),[=,&inData,&outData]
(平铺索引tidx)限制(amp)
{ 
tile_静态浮点localData[tileSize][tileSize];
localData[tidx.local[1]][tidx.local[0]]=inData[tidx.global];
tidx.barrier.wait();
索引outIdx(索引(tidx.tile_原点[1],
tidx.tile_原点[0])+tidx.local);
outData[outIdx]=localData[tidx.local[0]][tidx.local[1]];
});
因此,原子让您能够在所有线程之间安全地共享内存,而代价是一些显著的同步开销。原子是非阻塞的。屏障允许您在一个磁贴中跨线程同步执行和内存访问,它们是阻塞的。C++AMP没有将两者结合在一起的功能,您无法在GPU上的所有线程之间进行阻塞


这是编程模型的一个基本假设。所有线程都受到最小同步的约束,并且可以在线程之间很少或没有依赖关系的情况下运行。我的手册中关于优化和性能的章节中介绍了大部分内容。

并行化斐波那契算法并不实际,它实际上是一种串行算法。不过,你可以了解一些情况。并行化斐波那契不是重点,我知道它实际上是串行算法,但为什么它不起作用呢?无论如何,谢谢@Rogerrowland的帮助不幸的是,我认为没有简单的方法可以解决这个问题。AMP用于完全并行的进程,不支持用户以指定顺序执行线程。while循环可能触发TDR(超时检测和恢复)。如果您使用的是Windows 8,则可以为每个链接构建一个不易受TDR影响的加速器。然而,即使这样,也不能保证能很好地处理代码中的while循环。有趣的是,您可以使用近似算法对Fibonacci进行并行化,然后可以完全并行地执行(请参阅)
array<float, 2> inData(1000, 1000);
array<float, 2> outData(1000, 1000);

parallel_for_each(view, 
    inData.extent.tile<tileSize, tileSize>(), [=, &inData, &outData]
    (tiled_index<tileSize, tileSize> tidx) restrict(amp)
    { 
        tile_static float localData[tileSize][tileSize];
        localData[tidx.local[1]][tidx.local[0]] = inData[tidx.global];

        tidx.barrier.wait();
        index<2> outIdx(index<2>(tidx.tile_origin[1], 
                        tidx.tile_origin[0]) + tidx.local);
        outData[outIdx] = localData[tidx.local[0]][tidx.local[1]];
    });