본문 바로가기

SASS_Probe

공개되지 않은 하드웨어 특성을 실행으로 추론하는 방법

1. 문제의 출발점

CPU와 GPU 내부에는 덧셈기, 곱셈기, 부동소수점 연산기, 메모리 접근 장치, 명령어 스케줄러처럼 서로 다른 기능을 수행하는 회로 조합이 존재한다.

하지만 소프트웨어 개발자에게 공개되는 정보는 대부분 다음 수준에 머문다.

코어 수
클럭
캐시 용량
메모리 대역폭
지원 명령어 집합
이론적 최대 연산량

실제 성능을 결정하는 더 세부적인 마이크로아키텍처 정보는 전부 공개되지 않는 경우가 많다.

예를 들면 다음과 같다.

특정 명령어의 실제 지연시간
한 사이클에 시작할 수 있는 명령어 수
두 명령어가 같은 실행 파이프라인을 공유하는지
명령어 발행과 실행 유닛의 대응 관계
레지스터 읽기 포트의 제한
캐시 교체 정책
메모리 주소와 캐시·메모리 뱅크의 대응 관계
warp 스케줄러의 구체적인 발행 조건

uops.info 역시 공식 매뉴얼에 충분히 기록되지 않은 x86 명령어의 latency, throughput, port usage를 자동 생성 마이크로벤치마크로 측정한다. 이 결과는 컴파일러와 성능 모델에서 사용하기 쉽도록 기계 판독 가능한 형태로 제공된다.

따라서 하드웨어를 이해하는 방법은 두 가지로 나뉜다.

설계자가 공개한 구조를 읽는다.

또는

특정 프로그램을 실행하고 관측된 결과로 내부 구조를 추론한다.

두 번째 방법이 마이크로벤치마킹 기반 하드웨어 프로빙이다.


2. 먼저 구분해야 하는 것: ISA와 마이크로아키텍처

2.1 ISA

ISA는 Instruction Set Architecture, 즉 명령어 집합 구조다.

ISA는 하드웨어와 소프트웨어 사이의 약속을 정의한다.

어떤 명령어가 존재하는가
명령어가 어떤 operand를 받는가
레지스터가 어떻게 보이는가
명령어 실행 결과가 무엇이어야 하는가

예를 들어 다음 명령어의 의미는 ISA가 정의한다.

ADD R1, R2, R3

R1 = R2 + R3

2.2 마이크로아키텍처

마이크로아키텍처는 그 명령어를 실제로 어떻게 처리할지를 구현한 내부 구조다.

ADD 명령
   ↓
명령어 디코더
   ↓
내부 마이크로 연산
   ↓
스케줄러
   ↓
특정 실행 유닛
   ↓
결과 기록

같은 ISA를 지원하는 프로세서라도 다음은 서로 다를 수 있다.

실행 유닛의 수
파이프라인 깊이
명령어 지연시간
동시 발행 가능한 명령 수
캐시 구조
스케줄링 정책
전력 관리 방식

따라서 같은 기계어가 같은 결과를 만들더라도, 내부에서 거치는 회로 조합과 실행 시간은 하드웨어마다 달라질 수 있다.


3. 기존의 하드웨어 분석 방식

하드웨어 특성을 이해하는 전통적인 방식은 하나가 아니다. 일반적으로 여러 방법을 결합한다.


3.1 제조사 공식 문서

가장 먼저 사용하는 것은 제조사가 공개한 프로그래밍 가이드와 아키텍처 문서다.

GPU의 경우 CUDA Programming Guide는 프로그래밍 모델, 메모리 계층, 스레드 실행 구조, 하드웨어 기능을 설명한다.

공식 문서는 다음 정보를 얻는 데 유용하다.

프로그래밍 모델
지원 명령과 데이터 타입
메모리 공간의 종류
스레드와 block 구조
대략적인 실행 자원 구성
권장 최적화 방법

하지만 보통 다음 정보까지 완전히 제공하지는 않는다.

모든 명령어의 정확한 latency
실행 파이프라인별 명령어 대응 관계
내부 자원 충돌 조건
구체적인 스케줄러 정책
비공개 명령어 인코딩
세부 캐시 교체 정책

즉 공식 문서는 전체적인 지도를 제공하지만 모든 내부 도로를 공개하지는 않는다.


3.2 디스어셈블과 기계어 분석

컴파일된 프로그램을 분해해 실제 기계어를 확인하는 방법이다.

GPU에서는 일반적으로 다음 흐름을 볼 수 있다.

CUDA C++
   ↓
컴파일러 중간 표현
   ↓
PTX
   ↓
GPU별 실제 기계어 SASS

이 방식으로 다음을 확인할 수 있다.

소스 연산이 어떤 명령어로 번역됐는가
컴파일러가 연산을 제거하거나 결합했는가
반복문이 전개됐는가
FMA가 생성됐는가
메모리 명령이 몇 개 발생했는가
분기 명령이 어떻게 구성됐는가

디스어셈블은 매우 중요하지만, 기계어만 보고 다음을 모두 알 수 있는 것은 아니다.

그 명령어가 어느 실행 파이프라인을 사용하는가
결과가 몇 사이클 뒤에 나오는가
다른 명령어와 동시에 실행 가능한가
내부에서 몇 단계로 처리되는가

즉 디스어셈블은 무엇이 실행되는가를 보여주지만, 그 명령어가 하드웨어 내부에서 어떻게 실행되는가까지 완전히 보여주지는 않는다.


3.3 성능 프로파일러와 하드웨어 카운터

현대 프로세서는 내부 사건을 세는 성능 카운터를 제공한다.

GPU에서는 Nsight Compute가 CUDA 커널의 상세 성능 지표와 분석 기능을 제공한다. CUPTI는 이러한 프로파일링 및 트레이싱 도구를 개발할 수 있도록 성능 데이터 수집 인터페이스를 제공한다. 일부 metric을 수집할 때는 커널이나 애플리케이션을 여러 번 재실행할 수도 있다.

관측할 수 있는 항목의 예시는 다음과 같다.

실행된 명령어 수
메모리 transaction 수
캐시 hit rate
활성 warp 수
pipeline utilization
stall reason
메모리 대역폭
연산 처리량

이 방식의 장점은 실제 하드웨어 내부의 관측값을 얻을 수 있다는 것이다.

하지만 한계도 있다.

제조사가 제공하는 counter만 사용할 수 있다.
세대마다 metric 이름과 의미가 달라질 수 있다.
여러 원인이 같은 counter 변화로 나타날 수 있다.
측정 자체가 실행 조건을 바꿀 수 있다.
필요한 내부 정보가 counter로 노출되지 않을 수 있다.

따라서 프로파일러의 결과만으로 회로 구조를 직접 확정하기는 어렵다.


3.4 일반 애플리케이션 벤치마크

실제 게임, 렌더링, AI 모델, 행렬 곱셈과 같은 큰 프로그램을 실행해 전체 성능을 측정하는 방식이다.

초당 프레임
학습 처리량
추론 latency
행렬 곱셈 TFLOPS
메모리 복사 대역폭

이러한 벤치마크는 실제 사용자 성능을 평가하는 데 중요하다.

그러나 하나의 큰 프로그램에는 너무 많은 요소가 섞여 있다.

연산 명령
메모리 접근
캐시
분기
동기화
커널 실행 비용
라이브러리 구현
컴파일러 최적화

결과가 느리더라도 정확히 어떤 하드웨어 요소가 원인인지 분리하기 어렵다.

즉 일반 벤치마크는 다음 질문에는 적합하다.

이 하드웨어가 실제 작업을 얼마나 빠르게 처리하는가?

하지만 다음 질문에는 적합하지 않다.

이 명령어의 latency가 정확히 몇 사이클인가?
ADD와 MUL이 같은 파이프라인을 공유하는가?
L1 캐시의 교체 단위가 무엇인가?

3.5 시뮬레이터

GPGPU-Sim과 같은 도구는 GPU의 명령어 파이프라인과 메모리 계층을 모델링해 CUDA 또는 OpenCL 워크로드를 cycle 수준에서 분석할 수 있도록 한다.

시뮬레이터의 장점은 내부 상태를 직접 볼 수 있다는 것이다.

각 명령의 발행 시점
pipeline 대기 상태
cache miss 전파 과정
warp scheduling
메모리 요청 이동

또한 실제 하드웨어를 수정하지 않고도 가상의 구조를 시험할 수 있다.

캐시 용량 변경
실행 유닛 수 변경
스케줄러 정책 변경
메모리 대역폭 변경

하지만 시뮬레이터는 실제 하드웨어 그 자체가 아니라 하드웨어 모델이다.

정확한 실험을 위해서는 모델이 실제 하드웨어 행동과 충분히 일치해야 한다. 현대 GPU 시뮬레이션은 세부 모델링과 계산량 때문에 실행 비용이 매우 커질 수도 있다.

따라서 다음 순환 문제가 생긴다.

하드웨어를 이해하기 위해 시뮬레이터가 필요하다.

하지만

정확한 시뮬레이터를 만들려면 먼저 하드웨어 특성을 알아야 한다.

이 때문에 실제 장치에서 얻은 마이크로벤치마크 결과가 시뮬레이터 보정에도 사용된다.


4. 마이크로벤치마크 기반 블랙박스 분석

4.1 기본 개념

마이크로벤치마크는 하나의 하드웨어 특성만 최대한 분리해서 측정하는 작은 프로그램이다.

일반 벤치마크가 다음을 묻는다면,

이 GPU에서 딥러닝 모델이 얼마나 빠른가?

마이크로벤치마크는 다음처럼 묻는다.

FFMA 명령의 의존 latency는 몇 사이클인가?
독립적인 FP32 ADD를 매 사이클 몇 개 시작할 수 있는가?
INT 연산과 FP32 연산을 섞으면 서로 방해하는가?
shared memory의 bank mapping은 어떻게 되는가?

NVIDIA Volta와 Turing을 분석한 연구들은 마이크로벤치마크와 명령어 디스어셈블을 결합해 명령어 인코딩, 명령 지연시간, 메모리 계층, Tensor Core 동작 등 공식적으로 충분히 공개되지 않은 특성을 분석했다.

이 방법은 하드웨어 내부를 직접 열어 보는 것이 아니라, 입력과 출력의 관계를 통해 내부 행동을 추론한다.

통제된 입력 프로그램
        ↓
실제 하드웨어 실행
        ↓
시간·카운터·기계어 관측
        ↓
가능한 내부 구조 추론

5. 실행 프로그램은 하드웨어에 던지는 질문이다

마이크로벤치마크에서 프로그램은 단순한 작업이 아니다.

각각의 프로그램은 하드웨어에 특정한 질문을 던지는 실험 장치다.

예를 들어 다음과 같은 질문을 생각할 수 있다.

ADD 결과가 다음 ADD에 전달되기까지 몇 사이클이 필요한가?
서로 독립적인 ADD를 몇 개까지 병렬로 실행할 수 있는가?
ADD와 MUL은 독립된 실행 자원을 사용하는가?
작업 데이터가 어느 크기를 넘을 때 cache miss가 급증하는가?
특정 stride에서 shared memory 접근이 충돌하는가?

각 질문에 맞는 프로그램을 따로 설계한다.


6. 명령어 latency 측정

명령어 latency는 입력이 준비된 뒤 결과가 다음 연산에서 사용 가능해질 때까지 걸리는 시간이다.

이를 측정하려면 의존성 사슬을 만든다.

r1 = r1 + r2
r1 = r1 + r2
r1 = r1 + r2
r1 = r1 + r2
...

각 연산은 이전 연산 결과를 기다려야 한다.

ADD 1
  ↓ 결과 의존
ADD 2
  ↓ 결과 의존
ADD 3
  ↓
ADD 4

충분히 긴 사슬을 실행하고 전체 시간을 측정하면 다음과 같이 추정할 수 있다.

평균 의존 latency
≈
전체 실행 사이클 / 의존 명령어 수

실제 측정에서는 반복문, 타이머 읽기, 명령어 발행, 파이프라인 준비 등의 오버헤드를 따로 제거하거나 대조 실험으로 보정해야 한다.

uops.info는 operand 간 의존 관계를 고려한 자동 생성 마이크로벤치마크를 사용해 x86 명령어의 latency를 분석한다.


7. 명령어 throughput 측정

throughput은 명령 하나가 끝나는 데 걸리는 시간이 아니라, 일정 시간 동안 몇 개의 연산을 시작하거나 완료할 수 있는지를 나타낸다.

측정하려면 서로 의존하지 않는 연산을 여러 개 만든다.

r1 = r1 + a
r2 = r2 + b
r3 = r3 + c
r4 = r4 + d

각 명령은 다른 명령의 결과를 기다리지 않는다.

ADD r1 ─┐
ADD r2 ─┤
ADD r3 ─┼─ 병렬 실행 가능
ADD r4 ─┘

독립 accumulator 수를 늘리면서 처리량이 더 이상 증가하지 않는 지점을 찾는다.

accumulator 1개 → 의존성 때문에 낮은 처리량
accumulator 2개 → 처리량 증가
accumulator 4개 → 처리량 증가
accumulator 8개 → 더 이상 증가하지 않음

이 결과로 실행 파이프라인의 처리 한계나 명령어 발행 한계를 추론할 수 있다.


8. 서로 다른 연산이 같은 자원을 공유하는지 측정

두 명령어가 같은 실행 파이프라인이나 발행 자원을 공유하는지 알고 싶다면 먼저 각각을 따로 측정한다.

실험 A: ADD만 반복
실험 B: MUL만 반복

그다음 두 명령을 섞는다.

ADD
MUL
ADD
MUL
ADD
MUL

서로 다른 자원을 사용한다면

ADD 파이프라인 ───── 작동
MUL 파이프라인 ───── 작동

두 연산을 섞어도 각각의 처리량이 비교적 유지될 수 있다.

공통 자원을 사용한다면

ADD ─┐
     ├─ 공통 실행 자원 또는 발행 자원 경쟁
MUL ─┘

혼합 실험에서 처리량이 감소할 수 있다.

그러나 이 결과만으로 다음을 확정할 수는 없다.

두 명령어가 정확히 같은 물리적 연산 회로를 사용한다.

관측된 충돌의 원인은 여러 가지일 수 있기 때문이다.

같은 실행 파이프라인
같은 발행 포트
같은 스케줄러
같은 register read port
같은 writeback bus
전력 또는 클럭 제한

따라서 더 정확한 결론은 다음과 같다.

두 명령어가 공통된 내부 자원을 공유하는 행동이 관측되었다.

CPU의 실행 포트 추론에서도 단순 시간 측정과 성능 카운터, 수학적 자원 모델을 결합한다. 제한된 카운터만 제공되는 AMD Zen에서도 혼합 명령 실험과 제약 해결을 이용해 port mapping을 추론하는 연구가 이루어졌다.


9. 캐시와 메모리 구조 탐색

명령어 연산기뿐 아니라 메모리 계층도 실행 프로그램으로 추론할 수 있다.

9.1 작업 집합 크기 변화

접근하는 데이터 크기를 점점 늘린다.

4 KB
8 KB
16 KB
32 KB
64 KB
128 KB
...

특정 크기부터 접근 시간이 급격히 증가한다면 캐시 용량 경계를 의심할 수 있다.

낮은 latency
   ↓
특정 크기
   ↓
latency 급증

이는 데이터가 작은 캐시에서 더 큰 캐시 또는 주 메모리로 이동하기 시작했을 가능성을 보여준다.

9.2 Pointer chasing

다음 주소가 현재 메모리 값에 의해 결정되도록 만든다.

주소 A의 값 → 주소 B
주소 B의 값 → 주소 C
주소 C의 값 → 주소 D
A → B → C → D → ...

각 load가 이전 load의 결과에 의존하므로, 하드웨어가 여러 접근을 미리 병렬 실행하기 어렵다.

이를 통해 메모리 계층의 의존 load latency를 측정할 수 있다.

9.3 Stride sweep

메모리 접근 간격을 변화시킨다.

stride 1
stride 2
stride 4
stride 8
stride 16
stride 32
...

특정 stride에서 성능이 반복적으로 악화되면 다음 구조를 추론할 수 있다.

cache line 크기
cache set mapping
shared memory bank mapping
memory partition mapping

Volta와 Turing의 마이크로벤치마크 연구도 메모리 계층의 용량, latency, throughput과 여러 주소 매핑 특성을 세대별로 비교했다.


10. GPU에서 필요한 추가 실험

GPU에서는 CPU와 다른 실행 특성이 있으므로 추가 변수를 통제해야 한다.

warp 수
block 수
thread 수
register 사용량
shared memory 사용량
occupancy
분기 패턴
메모리 coalescing
명령어 dependency

예를 들어 동일한 명령어 사슬을 실행하더라도 warp 수를 바꾸면 결과가 달라질 수 있다.

warp 1개
→ instruction latency가 직접 노출될 가능성

warp 여러 개
→ 다른 warp 실행으로 latency 은폐

따라서 GPU 실험에서는 다음을 분리해야 한다.

개별 명령어 자체의 latency

전체 SM이 제공하는 throughput

warp 스케줄링으로 인해 감춰진 latency

Hopper와 Blackwell 같은 최근 GPU에 대해서도 instruction-level, memory-level, Tensor Core 수준의 마이크로벤치마크를 이용한 분석 연구가 이어지고 있다.


11. 하나의 프로그램이 아니라 Probe Suite가 필요하다

하드웨어 전체를 알아내려면 하나의 거대한 프로그램보다 목적별로 분리된 실행 프로그램 집합이 필요하다.

Hardware Probe Suite
│
├─ instruction_latency
│   ├─ integer_add
│   ├─ integer_mul
│   ├─ fp32_add
│   ├─ fp32_fma
│   └─ special_function
│
├─ instruction_throughput
│   ├─ dependent_chain
│   ├─ independent_2way
│   ├─ independent_4way
│   └─ independent_8way
│
├─ pipeline_interference
│   ├─ int_vs_fp
│   ├─ add_vs_mul
│   ├─ compute_vs_load
│   └─ fp32_vs_fp64
│
├─ memory_hierarchy
│   ├─ pointer_chasing
│   ├─ working_set_sweep
│   ├─ stride_sweep
│   ├─ cache_conflict
│   └─ bandwidth_saturation
│
├─ gpu_execution
│   ├─ warp_count_sweep
│   ├─ block_count_sweep
│   ├─ register_pressure
│   ├─ shared_memory_pressure
│   └─ occupancy_sweep
│
└─ tensor_operations
    ├─ data_type_sweep
    ├─ tile_shape_sweep
    ├─ instruction_latency
    └─ instruction_throughput

각 프로그램은 가급적 하나의 질문만 검증해야 한다.

한 실험
→ 하나의 주요 변수
→ 하나의 가설

변수가 여러 개 섞이면 어떤 요소가 결과를 만들었는지 판단하기 어렵다.


12. 마이크로벤치마크 개발 과정

12.1 가설 설정

먼저 확인하려는 하드웨어 특성을 명확하게 정의한다.

가설:

FP32 ADD와 INT ADD는 서로 다른 실행 자원을 사용한다.

12.2 통제 실험 설계

각 연산을 별도로 측정한다.

FP32 ADD만 실행
INT ADD만 실행

그다음 두 연산을 섞는다.

FP32 ADD + INT ADD 혼합

12.3 기계어 검증

소스 코드가 의도한 명령어로 컴파일됐는지 확인한다.

소스에서 ADD 작성
       ↓
컴파일
       ↓
SASS 확인
       ↓
실제 ADD 명령 존재 확인

이 과정이 없으면 다음과 같은 문제가 생길 수 있다.

컴파일러가 전체 계산을 제거
상수 folding 수행
ADD를 다른 명령으로 대체
FMA로 결합
loop를 예상과 다르게 전개
불필요한 load/store 삽입

따라서 마이크로벤치마크에서는 소스 코드와 실제 기계어를 함께 관리해야 한다.

12.4 반복 측정

한 번의 실행 결과만 사용하면 안 된다.

warm-up
반복 실행
동기화
시간 측정
이상치 확인
중앙값·최솟값·분산 기록

GPU에서는 클럭 변화, 온도, 전력 제한, 비동기 실행이 결과에 영향을 줄 수 있다.

12.5 성능 카운터 수집

실행 시간과 함께 counter를 측정한다.

실행 시간
+
instruction count
+
pipeline utilization
+
stall reason
+
cache metric

시간만 보면 여러 원인이 같은 결과를 만들 수 있다. 추가 관측값이 많을수록 가능한 가설을 더 좁힐 수 있다.

12.6 교차 검증

하나의 결과를 여러 실험으로 다시 확인한다.

실험 1: 혼합 명령 처리량
실험 2: pipeline utilization
실험 3: warp 수 변화
실험 4: register 사용량 변화

서로 다른 실험이 같은 방향을 가리킬 때 추론의 신뢰도가 높아진다.


13. 프로브 프레임워크의 구조

이 접근을 자동화하면 다음과 같은 시스템이 된다.

Probe Generator
      ↓
Compiler
      ↓
Binary / PTX / SASS Inspector
      ↓
Execution Harness
      ↓
Profiler / Counter Collector
      ↓
Result Analyzer
      ↓
Architecture Model

13.1 Probe Generator

실험 조건에 따라 소스 코드를 자동 생성한다.

입력 변수의 예시는 다음과 같다.

instruction type
dependency chain length
independent accumulator count
unroll factor
warp count
block count
register usage
shared memory usage
memory stride
working set size
iteration count

13.2 Compiler Controller

컴파일 조건을 고정하고 기록한다.

compiler version
optimization option
target architecture
register limit
link option
PTX version

마이크로벤치마크 결과에는 하드웨어뿐 아니라 컴파일러도 영향을 준다.

13.3 Binary Inspector

컴파일 결과가 실험 의도와 일치하는지 확인한다.

목표 명령어 존재 여부
명령어 개수
예상하지 않은 load/store
분기 명령
register 수
loop unroll 결과

13.4 Execution Harness

측정 환경을 통제한다.

warm-up
반복 횟수
CUDA synchronization
device-side timer
CUDA Event
실행 순서 무작위화
온도와 클럭 기록

13.5 Counter Collector

Nsight Compute 또는 CUPTI를 이용해 필요한 metric을 수집한다. Nsight Compute는 GUI와 CLI에서 CUDA 커널의 상세 성능 지표를 제공하며, baseline 비교와 결과 후처리에도 사용할 수 있다.

13.6 Result Analyzer

다음 값을 계산한다.

cycles per instruction
instructions per cycle
effective bandwidth
latency distribution
throughput saturation point
mixed-instruction interference ratio
cache transition point

13.7 Architecture Model

최종 결과를 기계가 읽을 수 있는 형태로 저장한다.

{
  "target": "sm_86",
  "instruction": "FFMA",
  "dependent_latency_cycles": 4,
  "issue_interval_cycles": 1,
  "likely_pipeline": "FP32",
  "measurement_variance": 0.03,
  "confidence": 0.91
}

여기서 likely_pipeline은 실제 물리 회로를 직접 확인한 값이 아니라 관측 결과에 기반한 추론이다.


14. 실험 결과를 어떻게 해석해야 하는가

마이크로벤치마크로 얻는 것은 정확한 회로도가 아니다.

알 수 있는 것:

외부에서 관측되는 실행 행동
자원 충돌 관계
처리량 한계
지연시간
메모리 계층의 경계
스케줄링 특성
직접 알기 어려운 것:

트랜지스터의 실제 배치
정확한 내부 배선
제조사의 RTL 코드
물리적인 회로 면적
내부 신호의 정확한 제어 방식

예를 들어 다음 결과가 관측됐다고 하자.

ADD와 MUL을 섞었을 때 처리량이 감소했다.

이것만으로 다음을 확정할 수는 없다.

ADD와 MUL이 같은 계산 회로를 사용한다.

가능한 설명은 여러 가지다.

같은 실행 파이프라인을 사용한다.
같은 instruction issue 자원을 사용한다.
같은 register read port를 사용한다.
같은 writeback 경로를 사용한다.
전력 제한으로 클럭이 감소했다.

따라서 분석 결과는 다음처럼 표현해야 한다.

확정적 표현:

ADD와 MUL은 같은 연산기를 사용한다.

더 적절한 표현:

ADD와 MUL을 동시에 실행할 때 공통 내부 자원에 대한
경쟁으로 해석할 수 있는 처리량 감소가 관측됐다.

15. 기존 방법과 프로브 방식의 관계

각 방법은 경쟁 관계가 아니라 서로 보완한다.

공식 문서
→ 공개된 기본 구조와 규칙 확인

디스어셈블
→ 실제 실행되는 명령어 확인

프로파일러
→ 내부 성능 사건 관측

마이크로벤치마크
→ 특정 하드웨어 특성 분리

시뮬레이터
→ 가설을 구조적 모델로 재현

실제 애플리케이션
→ 추론한 모델이 현실 성능을 설명하는지 검증

가장 신뢰도 높은 분석 흐름은 다음과 같다.

공식 문서 확인
      ↓
가설 설정
      ↓
마이크로벤치마크 설계
      ↓
기계어 검증
      ↓
실제 하드웨어 실행
      ↓
성능 카운터 수집
      ↓
다른 실험으로 교차 검증
      ↓
아키텍처 행동 모델 작성
      ↓
실제 커널 최적화로 검증

16. SASSScope와의 연결

현재 SASSScope는 PTX와 SASS를 관찰하는 도구에서 더 확장될 수 있다.

SASSScope
│
├─ Probe Definition
├─ CUDA Source Generator
├─ Build Controller
├─ PTX/SASS Inspector
├─ Execution Harness
├─ Nsight/CUPTI Collector
├─ Experiment Database
├─ Result Analyzer
└─ Architecture Cost Model

16.1 기존 역할

CUDA 코드 작성
      ↓
PTX 확인
      ↓
SASS 확인
      ↓
컴파일러가 어떤 명령어를 생성했는지 분석

16.2 확장된 역할

하드웨어 가설 작성
      ↓
가설 검증용 CUDA 코드 자동 생성
      ↓
PTX/SASS 검증
      ↓
실제 GPU에서 실행
      ↓
시간과 성능 카운터 수집
      ↓
명령 latency·throughput·충돌 관계 추론

즉 단순한 기계어 관찰 도구에서 다음으로 발전한다.

GPU 마이크로아키텍처 행동을 실험적으로 특성화하는 프로브 프레임워크


17. SASSScope에서 먼저 구현할 수 있는 실험

실험 1: 의존 FFMA latency

FFMA R0, R0, R1, R2
FFMA R0, R0, R1, R2
FFMA R0, R0, R1, R2
...

목적:

이전 FFMA 결과를 다음 FFMA가 사용할 수 있을 때까지의 시간 측정

실험 2: 독립 FFMA throughput

FFMA R0, R0, R1, R2
FFMA R3, R3, R4, R5
FFMA R6, R6, R7, R8
FFMA R9, R9, R10, R11

목적:

독립 명령을 이용해 FFMA pipeline의 최대 처리량 측정

실험 3: FP32와 INT 혼합

FFMA
IADD3
FFMA
IADD3
...

목적:

FP32와 INT가 동시에 처리 가능한 독립 실행 경로를 가지는지 추론

실험 4: shared memory bank stride

stride = 1
stride = 2
stride = 4
stride = 8
stride = 16
stride = 32
stride = 33

목적:

bank conflict와 주소 mapping 특성 관측

실험 5: register pressure sweep

register 16개
register 32개
register 48개
register 64개
register 96개

목적:

register 사용량 증가가 occupancy와 throughput에 미치는 영향 측정

18. 컴파일러 비용 모델로의 확장

프로브 결과는 단순한 하드웨어 분석 자료로 끝나지 않는다.

Hardware Probe
      ↓
명령 latency·throughput 모델
      ↓
자원 충돌 모델
      ↓
연산자별 비용 모델
      ↓
컴파일러 스케줄 선택

예를 들어 두 가지 lowering 후보가 있다고 하자.

후보 A:
FP32 연산이 많지만 명령어 수가 적음

후보 B:
INT와 FP32를 섞어 서로 다른 pipeline 활용

하드웨어 프로브를 통해 INT와 FP32가 독립적으로 실행될 수 있다는 결과를 얻었다면, 해당 GPU에서는 후보 B가 더 높은 처리량을 낼 가능성이 있다.

또 다른 예시는 다음과 같다.

연산자 A:
Tensor Core 사용
데이터 변환 명령 추가

연산자 B:
일반 FP32 Core 사용
변환 명령 없음

단순 FLOP 수만으로는 어느 쪽이 빠른지 판단하기 어렵다.

프로브 기반 비용 모델은 다음을 함께 고려할 수 있다.

명령어 latency
실제 throughput
pipeline 사용
데이터 변환 비용
register pressure
memory traffic
occupancy

즉 하드웨어 프로빙은 AI 컴파일러가 하드웨어별로 다른 최적화 결정을 내리게 하는 기반이 된다.


19. 최종 정의

이 프로젝트 방향을 기술적으로 정의하면 다음과 같다.

공개되지 않았거나 불충분하게 문서화된 CPU·GPU 마이크로아키텍처 특성을 추론하기 위해, 통제된 명령어와 메모리 접근 패턴을 자동 생성하고, 실제 기계어·실행 시간·성능 카운터를 함께 분석하는 프로브 기반 하드웨어 특성화 프레임워크.

조금 더 직관적으로 표현하면 다음과 같다.

내부 회로도를 직접 볼 수 없는 하드웨어에 서로 다른 실험 프로그램을 입력하고, 실행 결과를 관찰해 어떤 연산 경로와 자원 구조가 존재하는지 역으로 추론하는 작업이다.

핵심은 회로를 완벽하게 복원하는 것이 아니다.

실제 회로도 복원

보다는

소프트웨어 최적화에 충분한
하드웨어 행동 모델 구축

이 목적에 가깝다.


20. 결론

CPU와 GPU의 연산 성능은 단순히 명령어의 종류나 코어 수만으로 결정되지 않는다.

어떤 실행 회로가 존재하는가
각 회로가 몇 개 배치돼 있는가
명령어가 어느 경로로 전달되는가
여러 명령어가 어떤 자원을 공유하는가
데이터가 얼마나 빠르게 공급되는가

가 실제 성능을 결정한다.

하지만 이러한 마이크로아키텍처 정보는 전부 공개되지 않는다.

따라서 개발자는 다음과 같은 방식으로 하드웨어를 이해한다.

문서를 읽고
기계어를 확인하고
성능 카운터를 측정하고
작은 실험 프로그램을 실행하고
결과를 서로 비교한다.

결국 마이크로벤치마크 기반 하드웨어 탐색은 단순한 성능 측정이 아니다.

하드웨어에 통제된 질문을 반복해서 던지고, 그 응답으로 내부 구조에 대한 모델을 세우는 과학적 실험 과정이다.

그리고 이 결과가 컴파일러 비용 모델과 연결되면 다음 흐름이 완성된다.

하드웨어 행동 탐색
       ↓
마이크로아키텍처 모델
       ↓
연산자 비용 모델
       ↓
lowering·스케줄·커널 선택
       ↓
하드웨어 특화 코드 생성

따라서 SASSScope의 확장 방향은 PTX와 SASS를 보는 데서 끝나는 것이 아니라, 기계어가 실제 하드웨어에서 어떻게 실행되는지를 실험하고 모델링하는 것으로 정의할 수 있다.