내가 C++ 코드 다음 한 느린C++ AMP는
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;
};
이제 프로그램이 매우 느리게 코드를 실행합니다. 단지 몇 밀리 초가 느리지 만 실제 시간은 더 느립니다.
I는 또한 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를 배워야합니까?
추신. slownes는 정말로 나쁘다. 100 000 번 이상 걸리는 것처럼 (같은 시간에 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에 대한 프로그램을 수정하기 위해 지식을 사용하는 것이 좋습니다. –
전자에서 동기화를 호출 할 수 있는지 여부는 알 수 없지만 _sum에는 std :: 예외가 트리거되지 않습니다.가능한 랩톱에서 실행되기 때문에 GPU는 잠자기 모드 상태이고 AMP가 CPU로 돌아갑니다. 내 CPU 사용률이 ~ 10 %이지만 내 컴퓨터의 스레드 중 하나가 해당 기능의 90 %를 실행 중임을 나타냅니다. – Nyxeria