我具有以下在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