2013-03-24 1 views
1

는 내가 CUDA 라이브러리를 사용하여 급상승 신경 네트워크를 구현하고 다음 사항과 관련하여 진행하는 방법을 정말 확실하지 오전 오전 : 다양한 배열에크기를 모르는 많은 (1000+) 배열에 메모리를 어떻게 할당해야합니까?

  1. 할당 메모리 (cudaMalloc을). 지금까지 간단하게 cudaMalloc을 '손으로 사용하기'는 충분했습니다. 10 개가 넘는 배열을 만들 필요가 없었기 때문입니다. 그러나 이제 포인터를 만들고 수천 개의 배열에 메모리를 할당해야합니다.

  2. 각 배열에 할당 할 메모리 크기를 결정하는 방법. 배열의 높이는 postsynaptic 뉴런 ID의 경우 1 행, postsynaptic 뉴런의 시냅스 수의 경우 1 행, 해당 시냅스의 효능에 대해서는 1 행이지만 시간이 지남에 따라 변하는 미정의 길이입니다 나가는 시냅스의 수와 함께.

나는 CUDA 동적 메모리 할당 그러나 신경 세포 당 나가는 시냅스의 수는 100 내지 10000 등까지 다양 매우 느리고 각각의 배열에 필요한 최대 메모리를 할당의 아이디어 장난 삼아 생각해이라고 들었습니다 나는 이것이 1000 회의 뉴런을 가지고 있기 때문에 실행 불가능하다고 생각했다.

GPU의 많은 배열에 메모리를 할당하는 방법 및/또는 위의 작업에 대한 빠른 동적 메모리 할당을 코딩하는 방법에 대해 조언을 해 주시면 큰 호응을 얻습니다.

미리 감사드립니다.

+0

많은 작은 메모리 대신에 하나의 큰 메모리 할당을 해결할 수없는 이유가 있습니까? – talonmies

+0

많은 소규모 할당을 사용하려는 이유는 정보의 '구조'가 인접성 목록과 유사하기를 원했기 때문입니다. 즉, 네트워크의 각 노드에 대해 다른 노드가 있는지 알려주는 목록이 있습니다 (노드마다 3 행의 정보가 있기 때문에 제 경우를 제외하고는 '행렬'이 될 것입니다.) - 큰 3D 배열을 사용하면 많은 제로 요소가있는 것을 피할 수 있다고 생각했습니다. 이 제로 요소들이 메모리를 다 쓸 것이라고 생각하는 것이 맞습니까? – Boyentenbi

+0

사용 가능한 할당 자 (예 : cudaMalloc 또는 장치의 malloc)를 사용하거나 직접 할당자를 만드는 옵션은 두 가지가 있습니다. 속도에 대해 걱정하고 작은 할당을 많이한다면 자신의 할당자를 만드는 것이 아마도 길 일 것입니다.이것은 'cudaMalloc'을 한 번 또는 몇 번 발행 한 다음 필요에 따라 조각을 나누어서 포인터를 장치의 할당 된 영역에 인덱싱하는 방식입니다. 큰 3D 배열은 코딩을 단순화하지만 훨씬 많은 공간을 낭비 할 가능성이 있습니다. 스마트 할당자는 필요한만큼의 공간 만 떼어냅니다. –

답변

1

정말로이 작업을 수행하려는 경우 cudaMalloc을 원하는만큼 여러 번 호출 할 수 있습니다. 그러나, 그것은 아마 좋은 생각이 아닙니다. 대신 블록의 인접 스레드가 가능할 때마다 RAM의 인접 요소에 액세스 할 수 있도록 메모리를 배치하는 방법을 찾아보십시오.

스레드가 한 번에 32 개의 그룹 (워프) 단위로 실행된다는 것이 문제가되는 이유입니다. NVidia의 메모리 컨트롤러는 상당히 똑똑합니다. 인접한 스레드가 RAM의 인접 바이트를 요청하면 효율적으로 실행할 수있는 단일 요청으로 이러한로드를 통합합니다. 대조적으로 워프의 각 스레드가 임의의 메모리 위치에 액세스하는 경우 전체 워프는 32 개의 메모리 요청이 완료 될 때까지 대기해야합니다. 또한 카드의 메모리에 대한 읽기 및 쓰기는 한 번에 전체 캐시 라인에서 발생하기 때문에 캐시에서 제거되기 전에 읽은 모든 RAM을 스레드가 사용하지 않으면 메모리 대역폭이 낭비됩니다. 스레드 블록 내에서 일관된 메모리 액세스를 최적화하지 않으면 10 배에서 100 배까지 느려질 것입니다.

(측면 참고 :.. 위의 논의는 여전히 포스트 G80 카드에 적용되며, CUDA 하드웨어의 첫 번째 세대 (G80)이도 까다로워이었다 그것은 또한 프로그래머가 병합 동작을 원한다면 메모리 요청을 정렬 필수)

관련 문제