---
title: "SIMT에서 thread마다 상태가 달라도 독립 코어는 아닌 이유"
author: "브레이브브라우저쓰자"
published_at: "2026-11-01T23:47:03.079Z"
updated_at: "2026-10-06T03:15:27.361Z"
tags: ["simt"]
canonical_url: "https://ariser.io/@writer_a9817d5a8de0/simt%EC%97%90%EC%84%9C-thread%EB%A7%88%EB%8B%A4-%EC%83%81%ED%83%9C%EA%B0%80-%EB%8B%AC%EB%9D%BC%EB%8F%84-%EB%8F%85%EB%A6%BD-%EC%BD%94%EC%96%B4%EB%8A%94-%EC%95%84%EB%8B%8C-%EC%9D%B4%EC%9C%A0"
ai_assisted: true
---

# SIMT에서 thread마다 상태가 달라도 독립 코어는 아닌 이유

이 글은 AI가 활용됐습니다.

[원문](https://ariser.io/@writer_a9817d5a8de0/simt%EC%97%90%EC%84%9C-thread%EB%A7%88%EB%8B%A4-%EC%83%81%ED%83%9C%EA%B0%80-%EB%8B%AC%EB%9D%BC%EB%8F%84-%EB%8F%85%EB%A6%BD-%EC%BD%94%EC%96%B4%EB%8A%94-%EC%95%84%EB%8B%8C-%EC%9D%B4%EC%9C%A0)

CUDA 프로그램에서 thread마다 변수와 조건문을 쓰면 각각이 작은 CPU 코어처럼 보인다. 그러나 많은 thread를 선언하는 일과 각 thread에 독립된 명령 발행 장치를 배정하는 일은 다르다. SIMT를 이해하려면 프로그램이 표현하는 독립 상태와 하드웨어가 명령을 묶어 실행하는 방식을 나누어 보아야 한다.

## 독립 상태를 가진 thread가 명령을 함께 실행한다

NVIDIA의 CUDA 문서는 warp를 32개 thread의 묶음으로 설명한다. 각 thread는 자신의 상태를 갖지만 warp의 실행에서는 공통 명령과 그 명령에 참여하는 thread를 함께 관리한다. compute capability 7.0 이후의 independent thread scheduling도 이 묶음 실행을 없애는 기능은 아니다. [CUDA Programming Guide, SIMT Execution Model](https://docs.nvidia.com/cuda/cuda-programming-guide/03-advanced/advanced-kernel-programming.html#simt-execution-model)

예를 들어 32개 thread가 각각 `y[i]=2*x[i]+1`을 계산한다고 하자. 같은 곱셈 명령이 실행되어도 각 thread의 i와 x[i], 결과를 담는 상태는 다르다. 공통 명령이므로 데이터까지 하나라는 뜻은 아니다. 반대로 서로 다른 데이터를 갖는다는 사실만으로 32개의 임의 명령을 같은 시각에 따로 발행할 수 있다는 뜻도 아니다.

이 구분은 scalar thread 코드를 읽을 때 유용하다. thread 하나의 연산 경로를 먼저 이해하고, 성능을 평가할 때에는 같은 warp의 다른 thread가 어느 명령에 함께 참여하는지 살핀다. 개별 상태의 정확성과 실행 자원의 사용률은 서로 다른 관점이다.

## 37개 thread를 37개의 물리 실행 슬롯으로 읽지 않는다

하나의 1차원 block에 thread가 37개라면 warp 두 개로 나뉜다. 첫 warp에는 32개, 마지막에는 5개의 유효 thread가 있다. 설명용으로 두 warp가 같은 길이의 명령 경로를 한 번씩 실행하고, 명령마다 32개의 lane 자리가 있다고 세면 유효 연산 수는 37, 자리 수는 64다. 이 관점의 비율은 37/64, 약 57.8%다.

이 값은 실제 GPU 사용률이나 실행 시간의 예측이 아니다. 명령 처리량과 지연, 메모리 접근, 스케줄러 구조를 모두 지웠기 때문이다. 다만 thread 개수와 실행 묶음의 경계가 맞지 않으면 마지막 묶음에 사용하지 않는 자리가 생길 수 있음을 보여 준다.

block 크기를 키워 마지막 warp를 채우는 선택도 무조건 이득은 아니다. 더 많은 thread가 레지스터와 공유 메모리를 요구하면 동시에 배치할 block 수가 달라질 수 있다. 작업 크기가 작거나 메모리 병목이 크면 위의 lane 비율이 전체 성능을 결정하지 않을 수도 있다. 이 계산은 설계 질문의 시작점으로 사용한다.

## 독립 스케줄링은 암묵적인 순서를 허락하지 않는다

independent thread scheduling에서는 같은 warp 안의 thread가 항상 같은 명령 단계에 함께 있다고 가정한 코드가 문제가 될 수 있다. 문서도 예전의 암묵적인 warp 동시 실행에 의존하던 공유·동기화 코드를 재검토하도록 설명한다. [같은 문서, Independent Thread Scheduling](https://docs.nvidia.com/cuda/cuda-programming-guide/03-advanced/advanced-kernel-programming.html#independent-thread-scheduling)

가령 thread 0이 공유 위치에 값을 쓴 다음 thread 1이 읽는다면, 소스 코드에서 쓰는 문장이 먼저 보인다는 사실만으로 thread 사이의 순서가 생기지 않는다. ‘같은 warp니까 아마 같이 진행할 것’이라는 추측을 데이터 전달의 계약으로 사용해서는 안 된다. 참여 범위에 맞는 명시적인 동기화와 데이터 경합 없는 접근이 필요하다.

여러 thread가 같은 위치에 동시에 비원자적 쓰기를 하는 경우도 lane 수가 결과의 결정성을 보장하지 않는다. 합계를 구하려고 각 thread의 값을 같은 변수에 그대로 더하는 코드는 각자의 독립 상태와 공유된 결과의 갱신을 혼동할 수 있다. 정확한 협력 방법을 정한 뒤 성능을 평가해야 한다.

SIMT의 장점은 thread 수준의 코드를 써서 많은 작업을 표현하면서 묶음 실행의 처리량을 얻는 데 있다. thread를 독립 코어의 개수로 세기보다, 서로 다른 상태가 어떤 공통 명령에 참여하고 어떤 순서로 값을 교환하는지 확인하면 정확성과 성능을 같은 코드에서 더 분명하게 읽을 수 있다.

