C ++ AMP很慢

时间:2016-07-24 19:03:16

标签: c++ performance parallel-processing gpgpu c++-amp

我在C ++中有以下代码:

float Neuron::feedForward(std::vector<Neuron>& previousLayer){
float sum=0.0f;
for(int i=0;i<(int)previousLayer.size();i+=1){
    sum+=previousLayer[i].getOutput()*weigths[i];
}
output=Neuron::transferFunction(sum);
return output;

};

我转换成了这个:

float Neuron::feedForward(std::vector<Neuron>& previousLayer){
float sum=0.0f;
extent<1> e((int)previousLayer.size());

std::vector<float> ops(previousLayer.size());
for (int i = 0; i<(int)previousLayer.size(); i += 1) {
    ops[i] = previousLayer[i].getOutput();
}

array_view<const float, 1>_outputs(e, ops);
array_view<const float, 1>_weigths(e, weigths);
array_view<float> _sum(e);
_sum.discard_data();


parallel_for_each(e, [=](index<1> idx) restrict(amp) {
    _sum[idx] = _outputs[idx] * _weigths[idx];

});

for (int i = 0; i < e[0]; i += 1) {
    sum += _sum[i];
}

output=Neuron::transferFunction(sum);
return output;

};

现在程序运行的代码非常慢。不仅慢几毫秒,而且实际秒慢。

我也尝试在AMP代码中加上总和(仅更改):

array_view<float> _sum(1);
_sum.discard_data();

...

parallel_for_each(e, [=](index<1> idx) restrict(amp) {
_sum[0] += _outputs[idx] * _weigths[idx];

});

...

/*for (int i = 0; i < e[0]; i += 1) {
sum += _sum[i];
 }
 */

output=Neuron::transferFunction(_sum[0]);

但最后,代码只是:那么慢,用手动计算器我会更快。现在的问题是:为什么?我想如果我有一个拥有2000个重量的神经元,那么让GPU计算一切都会很棒。我错过了什么,还是我必须学习OpenCL或CUDA?

PS。慢下来真的很糟糕。就像它需要超过10万倍(同时我可以计算10 000个神经网络10次,我可以使用AMP计算2个完全相同的网络)。

1 个答案:

答案 0 :(得分:1)

使用sum[0]的代码几乎肯定会给出错误的结果,因为许多线程同时更新sum[0]

天真的实现应该可以工作,但效率非常低,因为将数据移入和移出GPU会产生很大的复制开销,而且你的计算量非常小。

但是,它的速度和你说的一样慢,你可能正在运行CPU上的WARP加速器。您可以使用以下代码查看可用的加速器。

https://ampbook.codeplex.com/SourceControl/latest#Samples/ShowAmpDevices/ShowAmpDevices.cpp

你在这里做的是减少。关于如何在GPU上有效地执行此操作有很多文章。您可以在此处找到C ++ AMP代码,其中显示了几种不同的实现:

CodePlex上的

C++ AMP: Accelerated Massive Parallelism with Microsoft Visual C++

在与代码一起出版的书中对它们进行了全面的解释。