我具有以下在C++代码:C++ AMP是慢
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万次(同时我可以计算20 000个神经网络10次,使用AMP我可以计算2个完全相同的网络)。
您可以尝试在parallel_for_each块之后的e上添加同步调用。根据此处的C++ AMP教程https://msdn.microsoft.com/en-us/magazine/hh882446.aspx,应该自动执行同步。但是,如果你不明确地调用synchronize(),你将失去异常,所以这可能会导致一些事情发生。 – hacoo
我怀疑你不知道如何使用AMP。看起来你坚持要将一定数量的产品积累到一个标量_sum [0]中。如果我理解了这个权利,那么您就迫使生成的代码将所有产品发送到持有sum [0](“多次通信”)的特定处理器,并且/或者强制执行全局锁定的所有更新(“大量的锁干扰“)。这些都不是有效的。我认为你会花点时间阅读数据并行编程,技术和陷阱,然后利用这些知识修改AMP的程序。 –
我不知道我是否可以在e上调用同步,但在_sum上没有触发std :: exception。是否有可能,因为我在笔记本电脑上运行,GPU以某种方式处于睡眠模式,并且AMP退回到CPU?尽管我的CPU使用率约为10%,这意味着我的电脑上的一个线程正在运行其90%的功能。 – Nyxeria