2012-08-31 2 views
4

일반적으로 워프 점유를 늘리기 위해 스레드 당 레지스터 압력을 낮추면 워프 레벨 멀티 스레딩 (TLP)을 통해 대기 시간을 숨길 수있는 기회가 더 많아집니다. 레지스터 압력을 줄이려면 스레드 로컬 메모리 당 또는 스레드 블록 공유 메모리 당 더 많은 것을 사용하십시오. CUDA nvcc 컴파일러는 쓰레드 당 더 적은 수의 레지스터를 사용해야 할 수도 있습니다. 이러한 접근법은 양호한 산술 대기 시간, 즉 메모리 r/w 액세스 요청에 대한 ALU 연산의 비율이 높은 작업 부하에 유용하다. 그러나 계산이 거의없고 빈번한 메모리 액세스가있는 대기 시간이 중요한 응용 프로그램의 경우이 방법은 실제로 성능을 저하시키는 경향이 있습니다.CUDA에서 스레드 당 레지스터 사용량 증가

대기 시간이 중요한 응용 프로그램의 경우 온칩 레지스터 또는 공유 메모리에서 최대한 많은 데이터를 가져온 다음 가능한 한 많이 사용하여 다음 데이터 청크로 바꾸십시오 전역 메모리. 물론 레지스터 압력을 증가 시키면 워프 점유가 줄어들지 만 빠른 온칩 레지스터를 사용하여 오프 칩 메모리 대기 시간을 감추고 있습니다. 스레드 레지스터 사용량을 늘리는 방법은 루프를 풀거나 ILP를 늘리거나 스레드 당 더 많은 출력 데이터를 계산하는 것입니다.이 방법은 기본적으로 더 많은 입력에 대해 동일한 작업을 수행하여 ILP를 증가시킵니다. 이 접근법은 Volkov (Lower Occupancy에서 더 나은 성과)에 의해 기본적으로 제안되었습니다.

이제 nvcc 컴파일러 드라이버에는 maxrregcount라는 명령 줄 옵션이있어서 스레드 당 레지스터 사용을 변경할 수 있습니다. 이 옵션을 사용하면 컴파일러가 스레드 당 레지스터 사용량을 줄 이도록 강요 할 수 있지만 강제로 증가시킬 수는 없습니다. 스레드 등록기 사용량을 늘리고 싶지만 루프 경계가 데이터에 따라 다르며 동적이기 때문에 커널 내부에서 루프를 풀어 낼 수없는 경우가 있습니다. 지금까지 몇 가지 트릭을 시도했지만, 스레드 레지스터 사용량을 늘리는 방법에 대한 아이디어가 부족합니다. 누구나 단일 CUDA 스레드의 레지스터 사용을 늘릴 수있는 방법을 제안 할 수 있습니까?

+0

죄송하지만이 질문은 완전히 불합리한 것처럼 보입니다. –

+0

@ 로저 달 (Robert Dahl) : 제가 언급 한 논문을 방금 읽었을 때, 제가 여기에서하려고하는 요점을 이해할 수 있습니다. – nurabha

답변

2

어느 정도까지이 질문은 Forcing CUDA to use register for a variable과 중복됩니다. 옵션을 꽤 잘 요약했습니다. 언 롤링과 명시적인 스칼라 변수 사용을 통해 레지스터 사용을 강제 할 수 없다면 나는 당신이 붙어있을 수 있다고 생각합니다.

동적 경계가있는 짝수 루프는 부분적으로 손으로 풀릴 수 있습니다. 루프의 풀린 부분 내에서 경계를 확인하기 만하면됩니다. 이렇게하면 레지스터 사용량이 늘어납니다.

또한 레지스터 사용량 증가와 대기 시간 감소 사이의 직접적인 관계가 보장되지 않는다고 생각합니다. 따라서 실제로는 레지스터 사용에 대한 지연 시간 감소에 집중해야합니다.

커널 대기 시간을 줄이려면 시도해야 할 몇 가지 사항이 있습니다.

  • (점유 계산기에 의해 결정된 것처럼) GPU에서 동시에 실행할 수있는 스레드 블록을 더 이상 실행하지 않습니다.
  • 커널에 대한 함수 매개 변수의 수를 최소화하십시오. 매개 변수가 커널 시작 중에 초기화되어야하므로 (많은 매개 변수로 인해 실행 오버 헤드가 증가 할 수 있기 때문입니다).
+0

나는 당신의 이전 글을 읽었습니다. 실제로 수동 언롤을하려고합니다. 처음에는 불가능한 것 같았지만 어젯밤에 어떤 트릭을 발견했습니다. 실제로 더 적은 인원을 할당하기 위해 컴파일러에게 할당량을 늘리려고했지만 인원을 늘리면 커널의 성능이 저하되는 것 같습니다. 그리고 왜 스레드 레지스터 당 증가가 성능을 향상시켜야한다고 생각합니다. 물론 점유가 감소하면 성능에 영향을 줄 수있는 한계점이있을 것입니다. 그러나 나는 그 트레이드 오프를 탐구해야한다고 생각한다. – nurabha

+0

Tesla C1060을 사용 중이며 스레드 당 레지스터 사용량이 32 인 경우 SM 당 점유를 50 % 또는 두 개의 스레드 블록으로 제한합니다. 필자가 보았 듯이 커널을 더 많은 스레드 블록 (2 개 대신 SM 당 4 개의 스레드 블록)으로 시작할 때 더 나은 결과를 얻습니다. 커널의 매개 변수 수는 너무 높다고 생각되는 순간에 약 15 개입니다. 어쩌면 몇 개의 배열과 매개 변수의 수를 연결할 필요가 있습니다. – nurabha

-2

이 질문의 답은 "상점에서 우유에 더 많은 돈을 어떻게 지불 할 수 있습니까?"라고 묻는 것과 같습니다. 질문은 거꾸로되어 있습니다. 당신이 물어야하는 것은 "나는 주어진 돈이 있습니다. 가능한 한 많은 우유를 얻기 위해 그것을 어떻게 사용합니까?"

오케이, 유추는 좋지만 기본적으로 레지스터 수를 늘리는 것이 그 자체의 목표 인 것처럼 질문합니다. 물론 목표는 성과를 높이는 것입니다.

우선, 결정할 사항은 당신이 생각하는만큼의 레지스터가 있습니까? 레지스터가 커널의 점유율 제한 요소 인 경우. 더 많은 레지스터를 사용하도록 코드를 변경하면 커널이 메모리 바운드 일 때 좋은 생각이 아닐 수도 있습니다.

점유가 다른 것으로 제한되는 경우, 더 많은 레지스터를 사용하여 성능을 향상시킬 수 있는지 물어볼 수 있습니다 (레지스터는 점유 제한 요소가 될 때까지 "자유"입니다).

이 목적을 위해 Space–time tradeoffs의 옵션을 살펴보십시오.

+2

인원에 대한 의견이 잘못 전달 된 것 같습니다. nurav는 인원이 증가함에 따라 그가 원하는 정반대의 효과를 나타낼 수 있기 때문에 인원 제한 리소스를 줄일 필요가 없습니다. 대기 시간이 늘어날 수 있습니다. 그는 처리량을 높이는 것이 아니라 대기 시간을 줄이기를 원합니다. 점유율을 높이면 대기 시간을 줄일 수 없습니다. 최대 점 (채울 유휴 슬롯이있는 경우)까지 점유를 늘리더라도 대기 시간은 늘어나지 않지만 SM이주기 당 하나의 명령을 완료하면 대기 시간이 늘어납니다. – harrism

+0

@harrism : 정확하게. 커널의 점유율을 높이면 실제로 성능이 저하됩니다. 점유율을 높이면 대기 시간이 – nurabha

+0

nurava 및 @harrism까지만 감소 할 수 있습니다. 정보 및 피드백에 감사드립니다. 나는이 논문을 읽었으며 지금 당신이 말하는 것에 대해 이해하고 있습니다. 그것은 내가 알고 있다고 생각하는 것에 반하는 것이지만, 완벽하게 이해합니다. 미래의 메모리 바운 딩 커널에서 이러한 기술을 직접 적용 할 것입니다. –

1

흥미로운 문제! 더 나은 성능을 제공하기 위해 ILP를 사용하는이 방법을 시도하고 있습니다! 사실, 스레드 당 할당되는 레지스터가 적은 기존 GPU의 구 조 조건 때문에 ILP를 사용하면 실제로 루프 풀기 (독립적 인 명령어)를 통해 더 많은 계산 작업을 위해 레지스터를 확보 할 수 있으므로 성능이 향상됩니다!

얼마나 많은 중첩 루프가 있습니까? 내부 루프를 풀어서는 안되는 경우 레벨을 올려 기회를 찾으십시오.

스레드 당 레지스터 사용을 늘리려면 시작한 블록 수를 줄 였습니까?
레지스터/스레드의 사용을 늘리려면 병렬로 수행 할 데이터 세트를 두 개 이상로드하십시오.

루프의 반복마다 독립적입니까? 중요한 것은 독립적 인 계산을 찾는 것입니다. 일괄 처리를 수행하는 것이 어떻습니까? 루프 카운트가 N이라고 가정하고, N/M으로 분할하고 독립적으로 분리합니다.

단서를 줄 때 제안을하기가 어렵습니다. P

+1

필자는 오래된 Tesla Architecture 1.3 컴퓨팅 기능도 사용하고 있습니다. 내 순차 알고리즘에는 네 단계의 루프 중첩이있었습니다. CUDA 커널을 구현 한 후에는 바깥 쪽 두 개의 루프를 병렬 처리하여 두 개로 줄였습니다. 내부 루프를 풀 수있는 방법이 없으며 지금은 외부 루프의 수동 풀기에 집중하고 있습니다. 기본적으로 각 루프 반복이 독립적이므로 외부 루프 반복마다 더 많은 출력을 생성하는 방식을 취하고 있습니다. 타일 ​​방식으로 생각했지만 내 경우에는 효과가 없습니다. – nurabha

+0

개선을위한 모든 업데이트가 있습니까? =) 필자는 내 생각에 Kepler 아키텍처 GPU로 이식하려고했지만 속도가 그다지 중요하지 않았습니다. Kepler는 이제 스레드 당 더 많은 레지스터를 할당합니다. –

+0

나는 테슬라 C1060을 계속했다. 나는 또한 어떤 speedups도 얻을 수 없었다. 나는 2 배와 3 배 언 롤을 시도했는데, 레지스터 사용이 초기 31에서 41로 증가한 다음 52로 증가했지만, 불행하게도 성능은별로 개선되지 않았습니다. 하지만 어쨌든, 나는 이미 커널에서 평균 32 배속과 최대 56 배속을 사용하고 있습니다. – nurabha

관련 문제