我在使用C++ AMP处理大型数组(超过65536个元素)时遇到麻烦。我正在使用C++放大器来计算多边形列表的法线,切线和切线 vector 。输入由一个位置数组(每个位置3个浮点数)和一个uv坐标数组(每个顶点2个浮点数)组成。在我的parallel_for_each函数中,我计算了法线,切线和切线(每组3个顶点各1个)。我将它们写回到数组(封装在array_view的数组中)。该算法如下所示:

concurrency::extent<2> ePositions(positionsVector.size() / 3, 3);
concurrency::array_view<const float, 2> positions(ePositions, positionsVector);
concurrency::extent<2> eUVs(uvsVector.size() / 2, 2);
concurrency::array_view<const float, 2> UVs(eUVs, uvsVector);
concurrency::extent<2> eNormalDirections(normalDirectionsVector.size() / 3, 3);
concurrency::array_view<float, 2> normalDirections(eNormalDirections, normalDirectionsVector);
normalDirections.discard_data();
concurrency::extent<2> eTangentDirections(tangentDirectionsVector.size() / 3, 3);
concurrency::array_view<float, 2> tangentDirections(eTangentDirections, tangentDirectionsVector);
tangentDirections.discard_data();
concurrency::extent<2> eBitangentDirections(bitangentDirectionsVector.size() / 3, 3);
concurrency::array_view<float, 2> bitangentDirections(eBitangentDirections, bitangentDirectionsVector);
bitangentDirections.discard_data();

concurrency::parallel_for_each(eNormalDirections.tile<1, 3>(), [=](concurrency::tiled_index<1, 3> t_idx) restrict(amp)
{
    < ... calculate the normals, tangents and bitangents and write them back ... >
}

normalDirections.synchronize();
tangentDirections.synchronize();
bitangentDirections.synchronize();

原始数据包含在positionsVector和uvsVector中。输出存储在normalDirectionsVector,tangentDirectionsVector和bitangentDirectionsVector中。三个位置(和相关的uv对)形成一个多边形。由于每个多边形仅需要一个法线,切线和切线,因此输出 vector 的大小比输入 vector 的大小小三倍。所有 vector 都封装在第一个代码块的array_view中。

只要要计算的法线数量小于65536,该算法就可以正常工作。一旦我需要65536个或更多法线,就会得到以下异常:



由于我要处理的几何图形包含65535个以上的多边形,因此这个限制对我来说是个问题。我无法想象C++ AMP只限于处理少于65536个元素。因此,我想知道我在方法中犯了什么错误,以及如何处理超过65536个元素的数组。

最佳答案

大多数GPU至少具有1 GB的全局内存,arrayarray_view都将数据存储在全局内存中。对于array_view,它会自动与主机(CPU)内存中的数据同步。它们还具有tile_static内存,这是非常有限的。在这种情况下,我认为您不会遇到任何与内存相关的限制。

计算域是传递给extentparallel_for_each,它描述了GPU上正在使用的线程数。 GPU只能执行有限数量的总线程。这是错误消息中描述的您已达到的极限。更改计算域的维数并不能解决您的问题,这是线程总数是一个问题,无论它们如何排列。这是GPU硬件的一般限制(使用CUDA也会发现类似的限制)。

您有几种方法可以解决此问题。

1)您可以将计算分解为小于总线程限制的块。这可能具有其他优点,即允许您使用上一个块的计算隐藏拷贝开销。

2)让计算域中的每个线程计算一个以上多边形的结果。这将允许您增加每个线程完成的工作量,如果它实际上受到数据传输的限制,则可以提高整个算法的效率。

3)1和2的组合。

关于c++ - 使用C++ AMP处理大型阵列(65536+个元素),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26162733/

10-12 16:31