thread addr in coalescing, thread 다중, 불연속 데이터 처리 예시

김민준·2026년 1월 1일

1) “각 스레드는 자기 addr을 정확히 요청한다”의 정확한 의미

"각 스레드는 자기 주소를 정확히 요청한다" = 스레드가 자기가 처리할 데이터의 주소를 정확히 요청한다?

조금 더 정확히 쓰면:

각 스레드는 커널 코드에 의해 계산된 인덱스 i에 대해,
그에 해당하는 메모리 주소 &a[i]를 요청한다.

즉 “스레드가 메모리 안에서 자기 고유 주소를 가진다”가 아니라,

  • 스레드는 실행 단위
  • 스레드는 “내가 읽을 데이터 주소”를 계산해서 load/store 요청
  • 요청 주소들의 패턴을 보고 하드웨어가 coalescing

이게 정확한 그림.


2) 스레드는 한 개 데이터만 처리해? 여러 개도 가능한가?

✅ 결론

둘 다 가능해. 커널이 어떻게 작성되었느냐에 따라 달라.


(A) 1 스레드 = 1 원소 처리 (가장 흔한 형태)

thread i → y[i] = f(x[i])

elementwise 연산에서 흔해.


(B) 1 스레드 = 여러 원소 처리 (자주 쓰는 최적화)

예를 들어 “한 스레드가 연속 원소 4개” 처리:

thread t:
  base = t * 4
  처리: x[base], x[base+1], x[base+2], x[base+3]

이렇게 하면:

  • 스레드 개수를 줄이고
  • 메모리 접근을 더 효율적으로 만들거나
  • 연산량 대비 메모리 병목을 줄이는 최적화가 가능해

특히 벡터화(vectorized load) 같은 테크닉이 여기랑 연결돼.


3) 그럼 스레드가 “불연속 데이터도 동시에 처리”할 수 있나?

✅ 가능은 하다

스레드가 코드로는:

x[0], x[1000], x[2000] 같은 불연속 주소를 한 스레드가 읽기

❗ 하지만 성능 관점에서 보통 불리해

왜냐하면:

  • 그 스레드 내부에서도 메모리 접근이 흩어져서 느리고
  • warp 전체로 봐도 coalescing이 깨지기 쉽기 때문

즉 “가능/불가능”이 아니라 “빠르냐/느리냐” 문제.


불연속 접근이 필요한 경우는?

대표적으로:

  • sparse 연산
  • gather/scatter (advanced indexing 계열)
  • 그래프/추천 시스템의 임베딩 lookup
  • top-k, sort 후 인덱싱 등

이런 건 “연속 접근”이 본질적으로 어려워서,
그 분야에서는 다른 최적화(캐싱, shared memory, sorting indices 등)를 따로 고민한다.


4) 전체 흐름

텐서의 dtype이 float32(4B)이고 contiguous라면
커널에서 i = ... + thread_id로 인덱스를 정하고
각 스레드는 &a[i] 주소를 load 요청한다.
warp(32 threads)가 요청한 주소들이 연속 구간에 모이면
하드웨어가 이를 적은 수의 memory transaction으로 묶어(coalescing) 가져오며,
그 결과 메모리 효율과 성능이 좋아진다.

profile
지금까지 해온 여러 활동들을 간략하게라도 정리해보고자 합니다.

0개의 댓글