我刚刚开始使用C ++ AMP(作为学习它的一种方式),而且不在性能方面获得预期效果,也许你可以帮助我。
要解决的问题非常简单, 我有一个Vector和一个Matrix结构(C ++代码,顺便说一句,我是C ++中的新手)
struct Vector
{
public : float X, Y, Z;
};
struct Matrix
{
public : float M11, M12, M13, M14,
M21, M22, M23, M24,
M31, M32, M33, M34,
M41, M42, M43, M44;
};
目标是将数百万个这些向量一遍又一遍地乘以相同的矩阵。 这里是执行计算的代码:
Vector compute(const Matrix matrix, const Vector vector) restrict(amp,cpu)
{
float tx = vector.X;
float ty = vector.Y;
float tz = vector.Z;
Vector result;
result.X = (matrix.M11 * tx) + (matrix.M12 * ty) + (matrix.M13 * tz) + matrix.M14;
result.Y = (matrix.M21 * tx) + (matrix.M22 * ty) + (matrix.M23 * tz) + matrix.M24;
result.Z = (matrix.M31 * tx) + (matrix.M32 * ty) + (matrix.M33 * tz) + matrix.M34;
return result;
}
现在我可以调用在CPU或GPU中运行此方法。
CPU:
Vector* cpu_compute(const Matrix matrix, const Vector *vectors, const int size)
{
Vector *result = (Vector*)malloc(size * sizeof(Vector));
for (int i = 0; i < size; ++i)
{
result[i] = compute(matrix, vectors[i]);
}
return result;
}
GPU:
Vector* gpu_compute(const Matrix matrix, const Vector *vectors, const int size)
{
Vector *result = (Vector*)malloc(size * sizeof(Vector));
array_view<const Vector, 1> vectors_view(size, vectors);
array_view<Vector, 1> result_view(size, result);
accelerator acc = pick_accelerator();
parallel_for_each(acc.default_view, vectors_view.extent, [=](index<1> idx) restrict(amp)
{
result_view[idx] = compute(matrix, vectors_view[idx]);
});
return result;
}
当使用2020万个向量运行此代码时,我得到以下结果:
我有几个惊喜。 首先,C#和C ++代码以几乎相同的速度运行。 其次,GPU没有我希望的那么快。
我知道你必须在内存转移中支付罚金,但我不认为这个例子会引起注意。 无论我投入多少数据,GPU都始终更慢。 这意味着我做错了,否则没有人会使用GPU来玩游戏,如果他们被一个核心CPU打败的话。
问题:这种计算在GPU上的性能是否比CPU更高?
由于
供参考: 我使用的是NVIDIA GeForce GTX 690和Intel Core i7 3930k的Windows 7(这使我无法使用WARP)。
答案 0 :(得分:3)
现在你正在支付将结果数据复制到GPU上的开销,即使你只是写过它。
array_view<Vector, 1> result_view(size, result);
result_view.discard_data()
您应该调用discard_data()以便不复制此数据。
即使考虑到这一点,你也不太可能在这里看到显着的加速,因为你正在做的工作量不会掩盖副本进出GPU的成本。
另一方面说明。您可以尝试将C ++版本编写为循环,并查看是否可以让编译器自动向量化计算。这是微不足道的,可能会给你一个显着的加速。
答案 1 :(得分:2)
可能你的内存访问计算比率很差。
内存访问很昂贵(从CPU复制到GPU并返回),因为复制内存的计算会很便宜(强大的GPU)。
您只需进行少量计算并经常访问新值。
要验证是这种情况,您可以注释掉计算并查看运行时间(仅用于复制)的数量。
另外,如果您刚开始grab the amp book samples on codeplex,那么您也可以了解哪种方式有效。