2013-10-30 4 views
2

전역 메모리를 사용해야하는 CUDA (v5.5) 응용 프로그램이 있습니다. 이상적으로는 상수 메모리를 사용하는 것을 선호하지만 상수 메모리가 부족해 오버 플로우가 전역 메모리에 저장되어야합니다. 또한 (GPU의 일부 축소 작업 이후에) 간혹 작성해야하는 변수가 있으며이를 전역 메모리에 저장하려고합니다.CUDA에서 전역 메모리 대 동적 전역 메모리 할당

읽기 위해서는 간단한 방법으로 전역 메모리에 액세스합니다. 내 커널은 for 루프 내부에서 호출되며, 커널 호출마다 모든 스레드가 오프셋이없는 동일한 전역 메모리 주소에 액세스합니다. 작성을 위해, 각 커널 호출 후에 GPU에서 감소가 수행되고 루프의 다음 반복 전에 전역 메모리에 결과를 기록해야합니다. 그러나 응용 프로그램에서 전역 메모리에 쓰는 것보다 훨씬 많은 읽기가 있습니다.

제 질문은 동적으로 할당 된 전역 메모리를 사용하는 것보다 전역 (변수) 범위에 선언 된 전역 메모리를 사용하는 것에 이점이 있는지 여부입니다. 필요한 전역 메모리 양은 응용 프로그램에 따라 달라 지므로 동적 할당이 그 이유 때문에 바람직합니다. 그러나 전역 메모리 사용량의 상한선을 알고 성능에 더 관심이 있습니다. 따라서 오버플로하지 않을 것임이 확실한 대규모 고정 할당을 사용하여 메모리를 정적으로 선언 할 수도 있습니다. 성능을 염두에두고, 한 가지 형태의 전역 메모리 할당을 다른 것보다 선호하는 이유가 있습니까? 그것들은 GPU의 동일한 물리적 인 장소에 존재하고 동일한 방식으로 캐싱 되었습니까? 아니면 두 형식에 대해 다른 읽기 비용이 필요합니까?

답변

9

Global memorystatically 할당 될 수 쿠다 C 권장 가이드 메모리 최적화 부 (__device__ 사용) dynamically (장치 malloc 또는 new 사용)을 참조하고 CUDA runtime (예 cudaMalloc을 이용한 비아주세요).

위의 모든 방법은 물리적으로 동일한 유형의 메모리, 즉 온보드 (그러나 온칩은 아님) DRAM 서브 시스템에서 조각 된 메모리를 할당합니다. 이 메모리는 할당 방식에 관계없이 동일한 액세스, 통합 및 캐싱 규칙을가집니다 (따라서 일반 성능 고려 사항은 동일합니다).

동적 할당은 일정하지 않은 시간이 걸리기 때문에 프로그램의 시작 부분에 정적 (즉 __device__) 메소드를 사용하거나 런타임 API를 통해 할당을 한 번 수행하면 코드 성능이 향상 될 수 있습니다 (예 : cudaMalloc 등) 성능에 민감한 코드 영역에서 동적으로 메모리를 할당하는 시간을 피할 수 있습니다.

또한 3 가지 방법은 장치 코드에서 유사한 C/C++와 유사한 액세스 방법을 사용하지만 호스트와는 다른 액세스 방법을 사용합니다. 정적으로 할당 된 메모리는 cudaMemcpyToSymbolcudaMemcpyFromSymbol과 같은 런타임 API 함수를 사용하여 액세스되며 런타임 API 할당 메모리는 일반 cudaMalloc/cudaMemcpy 유형 함수를 통해 액세스되며 동적으로 할당 된 전역 메모리 (장치 newmalloc)는 호스트에서 직접 액세스 할 수 없습니다.

+0

감사합니다. 내가 가지고있는 질문에 더하여, 나는 심지어 묻지도 않았다. –

1

우선 메모리 액세스 병합을 고려해야합니다. 사용중인 GPU에 대해 언급하지 않았습니다. 최신 GPU에서 석탄 엮어 진 메모리 읽기는 상수 메모리와 동일한 성능을 제공합니다. 가능한 한 석탄으로 엮어서 읽고 쓰는 것이 좋습니다.

또 다른 텍스처 메모리를 사용할 수 있습니다 (데이터 크기가 맞으면). 이 텍스처 메모리에는 캐싱 메커니즘이 있습니다. 이전에 전역 메모리 읽기가 병합되지 않은 경우에 사용됩니다. 그러나 최신 GPU는 텍스처와 전역 메모리에 거의 동일한 성능을 제공합니다.

통합 된 문제가 여전히 존재하기 때문에 전역 적으로 선언 된 메모리가 동적으로 할당 된 전역 메모리보다 더 많은 성능을 제공한다고 생각하지 않습니다. 또한 글로벌 (가변) 범위에서 선언 된 전역 메모리는 CUDA 전역 메모리의 경우 불가능합니다. 전역 적으로 (프로그램에서) 선언 할 수있는 변수는 상수 메모리 변수와 텍스처입니다. 우리는 커널에 인자로 넘겨 줄 필요가 없습니다. 메모리 최적화를위한

http://docs.nvidia.com/cuda/cuda-c-best-practices-guide/#memory-optimizations

+0

포인터 주셔서 감사합니다. Amazon AWS에서 Tesla M2050을 사용하고 있습니다. 나는 합병 문제를 이해한다. 하지만 정적 인 대 동적으로 할당 된 전역 메모리의 병합 읽기간에 차이가 있는지는 제가 추측하는 질문의 핵심입니다. 또한, "전역 적으로 선언 된 유일한 변수는 상수 메모리 변수와 텍스처입니다."라는 마지막 줄에 대해서는 잘 모르겠습니다. 이 (https://developer.nvidia.com/content/how-access-global-memory-efficiently-cuda-cc-kernels)에 따르면 CUDA 전역 메모리에는 전역 (가변) 범위가 있습니다. 이 링크는 내 원래 질문을 해결하지 않습니다. –

+0

메모리 최적화에 대한 자세한 내용은 cuda c 모범 사례 안내서의 메모리 최적화 섹션을 참조하십시오. http://docs.nvidia.com/cuda/cuda-c-best-practices-guide/#memory-optimizations – Sijo