2017-11-15 15 views
2

입니다. Julia에서 주로 매트릭스 작업을 할 때 속도를 높이고 코드를 최적화하는 방법을 보았습니다.Julia에서 ArrayFire를 통해 GPU에서 작업하는 코드를 작성하는 가장 좋은 방법은

- 줄 대신 행 단위로 작업하면 줄리아가 행렬을 저장하는 방식입니다.

-On 루프는 환영의 당신이 추천 할 수 @inbounds@simd 매크로

된 경위, 기능, 매크로 또는 방법을 사용할 수 있습니다 : D

그러나 내가 ArrayFire 사용할 때 위의 예제가 작동하지 않는 것 같다 GPU에 저장된 매트릭스와 함께 패키지, CPU와 GPU의 유사한 코드는 GPU를 선호하지 않는 것 같습니다. 어떤 경우에는 훨씬 느리게 실행됩니다. 그렇게해서는 안된다고 생각합니다. 문제는 다음과 같습니다. 코드를 작성합니다. 도움이 될 것입니다.

답변

3

GPU 컴퓨팅은 최적화 된 GPU 커널에서 가능한 한 많이 수행해야합니다. GPU 어레이를 인덱싱하는 것은 하나의 값을 다시 CPU에 복사하는 작은 커널입니다. 이것은 성능면에서 정말 좋지 않으므로 GPUArray를 인덱싱하지 않아야합니다 (모든 구현에 해당됩니다! 하드웨어 문제 일뿐입니다!)

따라서 GPU 용 루핑 코드를 작성하는 대신 방송 ("벡터화") 코드를 작성해야합니다. v0.6 broadcast changes을 사용하면 브로드 캐스트 된 작업이 루프만큼 효율적이므로 (this bug을 누르지 않는 한) 일반 코드에서이를 피할 이유가 없습니다. 그러나 방송이 루핑보다 빠르며 GPU가 큰 경우입니다.

이유를 설명해 드리겠습니다.

@. A = B*C + D*E 

이 절감

A .= B.*C .+ D.*E 

에 다음에 절감 : 거기에 당신이 전체 방송 융합 익명 함수를 가지고

broadcast!((b,c,d,e)->b*c + d*e,A,B,C,D,E) 

공지 사항 당신은 코드를 수행 할 때. GPUArray의 경우이 값을 덮어 쓰므로이 융합 된 연산을 요소별로 수행하는 단일 GPU 커널이 ​​자동으로 생성됩니다. 따라서이 전체 작업을 수행하는 데 오직 하나의 GPU 커널 만 필요합니다! GPU 컴퓨팅을 수행하는 R/Python/MATLAB 방식보다 훨씬 효율적이라는 점에 유의하십시오. 이러한 벡터화 된 형식은 일시적이며 여기에 4 개의 커널이 필요하기 때문에 여기에는 임시 배열이없고 단일 커널입니다. 만약 당신이 직접 커널을 작성했다면 그것을 쓸 것입니다. 따라서 브로드 캐스트를 악용하면 GPU 계산이 빨라집니다.

+0

답변을 주셔서 감사합니다. GPU를 사용하는 작업이 CPU에서 전통적으로 수행하는 작업과 비교적 다르다는 것을 알 수 있습니다. 선형 대수학 작업을하고 있으며, ArrayFire 패키지가 여러 가지 유용한 기능을 제공하지만 직접 작성해야합니다. 왜냐하면 함수를 적용해야하는 행렬은 상대적으로 다르니까요. 예 : Skyline Storage (SKS) 형식으로 저장된 희소 행렬로, 매트릭스를 저장하거나 작업 할 수있는 기능이 없습니다. 요약하자면, 설명 할 부분이 많습니다. 감사합니다. – 4lrdyD