Lec9 - VLIW

한국어판 강의자료 · 31쪽
1쪽
p.1CSED503 고급 컴퓨터 구조 – 강의 9 VLIW
2쪽
p.2superscalar(초순차 처리) control logic scaling(제어 논리 확장)
  • 각 발행된 명령어는 W×L개의 명령어와 비교해야 하므로, 하드웨어 증가량은 W×(W×L) 비례한다.
  • 순차적 머신의 경우, L은 파이프라인 지연과 관련 있으며, 발행 시점에 확인된다 (인터록 또는 scoreboard(스코어보드)를 통해).
  • 비순차적 머신의 경우, L은 명령어 버퍼(명령어 창 또는 재정렬 버퍼)에 머무르는 시간도 포함되며, 쓰기 완료(완료) 시점에 태그를 방송하여 대기 중인 명령어에 확인한다.
  • issue width w(발행 폭 W)가 증가함에 따라, 더 많은 병렬성을 찾기 위해 더 큰 instruction window(명령어 창)이 필요하다 (더 많은 비행 중 명령어 상태를 추적해야 함) → 더 큰 lifetime l(수명 L) → 비순차적 제어 논리는 W²보다 빠르게 증가 (~W³).
  • lifetime l(수명 L)
  • 발행 그룹
  • 이전에 발행된 명령어
  • issue width w(발행 폭 W)
3쪽
p.3비순차적 제어 복잡성: MIPS R10000
  • 제어 논리
  • [SGI/MIPS Technologies Inc., 1995]
4쪽
p.4순차적 ISA의 한계
  • 명령어 의존성 확인
  • superscalar(초순차 처리)기
  • a = foo(b);
  • for (i=0, i<
  • 순차적 소스 코드
  • 초순차 컴파일러
  • 독립된 연산 찾기
  • 연산 스케줄링
  • 순차적 머신 코드
  • 실행 스케줄링
5쪽
p.5VLIW: very long instruction word(매우 긴 명령어 단어)
  • 스케줄링 복잡성을 컴파일러로 이동하여 하드웨어 제어 논리를 단순화한다.
  • 더 많은 실행 자원을 추가해 성능을 향상시킬 수 있다.
  • 여러 연산을 하나의 명령어에 패킹한다.
  • 각 연산 슬롯은 고정된 기능을 위한 것이다.
  • 고정된 연산 지연이 명시된다.
  • 아키텍처는 다음을 보장해야 한다:
  • intra-instruction parallelism(명령어 내 병렬성) → 명령어 간 RAW 확인 없음
  • 데이터 준비 전에 데이터 사용 없음 → 데이터 No-Interlocks(인터록 없음)
  • 정수 유닛 2개, 단일 사이클 지연
  • 로드/스토어 유닛 2개, 세 사이클 지연
  • 부동소수점 유닛 2개, 네 사이클 지연
  • 정수 연산 2
  • 메모리 연산 1
  • 메모리 연산 2
  • 부동소수점 연산 1
  • 부동소수점 연산 2
  • 정수 연산 1
6쪽
p.6초기 VLIW 기계
  • FPS AP-120B (1976)
  • 호스트 머신(예: PDP-11)에 연결된 과학용 배열 처리기
  • 상용화된 넓은 명령어 폭 기계의 첫 사례
  • software pipelining(소프트웨어 파이프라인)과 loop unrolling(루프 전개)를 사용한 수동 벡터 수학 라이브러리 작성
  • Multiflow Trace (1987)
  • 예일 대학 Fisher 연구팀의 아이디어 상용화, ‘trace scheduling(트레이스 스케줄링)’ 포함
  • 7, 14, 또는 28개의 연산/명령어 구성 가능
  • 28개의 연산이 1024비트 명령어 단어에 패킹됨
  • Cydrome Cydra-5 (1987)
  • 256비트 명령어 단어에 7개의 연산 인코딩
  • 회전식 레지스터 파일
7쪽
p.7VLIW 컴파일러의 책임
  • 병렬 실행을 극대화하기 위해 연산을 스케줄링한다
  • intra-instruction parallelism(명령어 내 병렬성)을 보장한다
  • data hazard(데이터 위험)을 피하기 위해 스케줄링한다 (인터록 없음)
  • 일반적으로 명령어 사이에 명시적인 NOP을 삽입한다
8쪽
p.8루프 실행
  • 1회 루프당 FP 연산 수는?
  • for (i=0; i<N; i++)
  • B[i] = A[i] + C;
  • Int1 Int 2
  • M1
  • M2
  • FP+
  • FPx
  • loop:
  • fld
  • add x1
  • fadd
  • fsd
  • add x2
  • bne
  • 1 fadd / 8 cycles = 0.125
  • loop: fld f1, 0(x1)
  • add x1, 8
  • fadd f2, f0, f1
  • fsd f2, 0(x2)
  • add x2, 8
  • bne x1, x3, loop
  • 컴파일
  • 스케줄링
  • 단일 사이클 INT 연산, 세 사이클 LD/ST, 네 사이클 FP 연산을 가정
9쪽
p.9loop unrolling(루프 전개)
  • for (i=0; i<N; i++)
  • B[i] = A[i] + C;
  • for (i=0; i<N; i+=4)
  • {
  • B[i] = A[i] + C;
  • B[i+1] = A[i+1] + C;
  • B[i+2] = A[i+2] + C;
  • B[i+3] = A[i+3] + C;
  • }
  • 전개 인자로 나누어지지 않는 N 값에 대해 최종 정리 루프를 처리해야 한다
  • 내부 루프를 4회 반복을 동시에 수행하도록 전개한다
10쪽
p.10loop unrolling(루프 전개)된 코드의 스케줄링
  • loop: fld f1, 0(x1)
  • fld f2, 8(x1)
  • fld f3, 16(x1)
  • fld f4, 24(x1)
  • add x1, 32
  • fadd f5, f0, f1
  • fadd f6, f0, f2
  • fadd f7, f0, f3
  • fadd f8, f0, f4
  • fsd f5, 0(x2)
  • fsd f6, 8(x2)
  • fsd f7, 16(x2)
  • fsd f8, 24(x2)
  • add x2, 32
  • bne x1, x3, loop
  • 스케줄링
  • Int1
  • Int 2
  • M1
  • M2
  • FP+
  • FPx
  • loop:
  • Unroll 4 ways
  • fld f1
  • fld f2
  • fld f3
  • fld f4
  • add x1
  • fadd f5
  • fadd f6
  • fadd f7
  • fadd f8
  • fsd f5
  • fsd f6
  • fsd f7
  • fsd f8
  • add x2
  • bne
  • 1회 루프당 FLOPS 수는?
  • 4 fadds / 11 cycles = 0.36
  • 하드웨어 자원을 더 잘 활용할 수 있을까?
  • *코드 크기와 사용된 레지스터 수가 증가한 점을 주목
11쪽
p.11software pipelining(소프트웨어 파이프라인)
  • software pipelining(소프트웨어 파이프라인)
  • 관찰: 루프의 반복이 독립적이라면, 서로 다른 반복에서 명령어를 가져와 ILP를 얻을 수 있다
  • 루프를 재구성하여 각 반복이 원래 루프의 서로 다른 반복에서 선택된 명령어로 구성되도록 한다
12쪽
p.12software pipelining(소프트웨어 파이프라인)
  • 1회 루프당 FLOPS 수는?
  • loop: fld f1, 0(x1)
  • fld f2, 8(x1)
  • fld f3, 16(x1)
  • fld f4, 24(x1)
  • add x1, 32
  • fadd f5, f0, f1
  • fadd f6, f0, f2
  • fadd f7, f0, f3
  • fadd f8, f0, f4
  • fsd f5, 0(x2)
  • fsd f6, 8(x2)
  • fsd f7, 16(x2)
  • add x2, 32
  • fsd f8, -8(x2)
  • bne x1, x3, loop
  • Int1
  • Int 2
  • M1
  • M2
  • FP+
  • FPx
  • 4회 전개 후
  • fld f1
  • fld f2
  • fld f3
  • fld f4
  • fadd f5
  • fadd f6
  • fadd f7
  • fadd f8
  • fsd f5
  • fsd f6
  • fsd f7
  • fsd f8
  • add x1
  • add x2
  • bne
  • fld f1
  • fld f2
  • fld f3
  • fld f4
  • fadd f5
  • fadd f6
  • fadd f7
  • fadd f8
  • fsd f5
  • fsd f6
  • fsd f7
  • fsd f8
  • add x1
  • add x2
  • bne
  • fld f1
  • fld f2
  • fld f3
  • fld f4
  • fadd f5
  • fadd f6
  • fadd f7
  • fadd f8
  • fsd f5
  • add x1
  • loop:
  • 반복
  • 프롤로그
  • 에필로그
  • 4 fadds / 4 cycles = 1
13쪽
p.13software pipelining(소프트웨어 파이프라인) vs. loop unrolling(루프 전개)
  • software pipelining(소프트웨어 파이프라인)은 루프당 한 번만 시작/종료 비용을 지불하지만, loop unrolling(루프 전개)는 반복마다 한 번씩 지불한다.
  • 시간에 따른 성능: loop unrolling(루프 전개)는 반복마다 시작 오버헤드와 종료 오버헤드가 반복되지만, software pipelining(소프트웨어 파이프라인)은 루프당 한 번만 발생한다.
14쪽
p.14루프 외부 코드는 어떻게 되나요?
  • 브랜치는 제어 흐름이 많은 비정형 코드에서 basic block(기본 블록) 크기를 제한한다.
  • 개별 basic block(기본 블록) 내에서 ILP(명령어 수준 병렬성)를 찾는 것이 어렵다.
15쪽
p.15trace scheduling(트레이스 스케줄링) [Fisher, Ellis]
  • 가장 흔한 브랜치 경로를 나타내는 basic block(기본 블록)의 연속(트레이스)을 선택한다.
  • profiling feedback(프로파일링 피드백) 또는 컴파일러 히우리스틱을 사용하여 흔한 브랜치 경로를 찾는다.
  • 전체 '트레이스'를 한 번에 스케줄링한다.
  • 트레이스를 벗어나는 브랜치를 처리하기 위해 fixup code(수정 코드)를 추가한다.
16쪽
p.16"클래식" VLIW의 문제점
  • Object-Code compatibility(객체 코드 호환성): 모든 기계마다 코드를 재컴파일해야 하며, 같은 세대의 두 기계 사이에서도 마찬가지다.
  • 객체 코드 크기: instruction padding(명령어 패딩)이 명령어 메모리/캐시를 낭비한다. loop unrolling(루프 전개)/software pipelining(소프트웨어 파이프라인)은 코드를 복제한다.
  • variable memory latency(변동 메모리 지연)을 위한 스케줄링: 캐시와/또는 메모리 벤드 충돌로 인해 정적 예측 불가 변수성이 발생한다.
  • 브랜치 확률을 아는 것: 프로파일링은 빌드 프로세스에 추가적인 단계가 필요하다.
  • statically unpredictable branches(정적 예측 불가 브랜치)를 위한 스케줄링: 최적의 스케줄은 브랜치 경로에 따라 달라진다.
17쪽
p.17VLIW 명령어 인코딩
  • 사용되지 않는 필드의 영향을 줄이기 위한 기법:
  • 메모리에서 compressed format(압축 형식) 사용, i-cache refill(I-캐시 리필) 시 전개
  • • Multiflow Trace에서 사용
  • • 명령어 주소 지정 문제를 유발함
  • mark parallel groups(병렬 그룹 마킹)
  • • TMS320C6x DSP 및 인텔 IA-64에서 사용
  • single-op VLIW instruction(단일 연산 VLIW 명령어) 제공
  • • Cydra-5 UniOp 명령어 – "다섯 개의 순차 명령어로 해석되며, 명시적으로 인코딩된 지연이 포함됨"
18쪽
p.18인텔 이타니엄, EPIC IA-64
  • EPIC은 아키텍처 스타일(예: CISC, RISC)이다.
  • EPIC(명시적 병렬 명령어 계산)
  • 기본적으로 VLIW와 유사하지만 더 큰 유연성을 가진다.
  • IA-64는 인텔이 선택한 ISA(예: x86, MIPS)이다.
  • IA-64 = intel architecture 64-bit(인텔 아키텍처 64비트)
  • • 널리 사용되는 x86-64 ISA(또는 AMD64, 인텔 64)와는 다름
  • RISC 스타일, 레지스터-레지스터 명령어 세트
  • Object-Code compatibility(객체 코드 호환성) VLIW
  • merced(머서드)는 첫 번째 이타니엄 구현체(예: 8086)
  • 첫 번째 고객 출하 예정: 1997년(실제로는 2001년)
  • McKinley(맥킨리)는 두 번째 구현체로 2002년 출시
  • 최근 이타니엄 프로세서(킷슨)는 2017년에 출시됨
19쪽
p.198코어 이타니움 ‘poulson(폴슨)’ [Intel 2011]
  • 8코어 / 16스레드
  • 1사이클 16KB L1 I&D 캐시
  • 9사이클 512KB L2 I-캐시
  • 8사이클 256KB L2 D-캐시
  • 32MB 공유 L3 cache(L3 캐시)
  • 초당 6명령어 가져오기 (두 개의 128비트 번들)
  • 초당 최대 12명령어 실행
  • 32nm CMOS 기술로 544mm²
  • 30억 개 이상의 트랜지스터
20쪽
p.20IA-64 명령어 형식
  • template bits(템플릿 비트)는 인접한 bundle(번들) 내 다른 명령어들과의 grouping(그룹화)를 설명한다
  • 각 그룹은 병렬로 실행될 수 있는 명령어들을 포함한다 (그룹 내 명령어 간 의존성 없음)
  • 128비트 명령어 bundle(번들)
  • 그룹 i, i+1, i+2, i-1
  • bundle(번들) j, j+1, j+2, j-1
  • 41비트, 41비트, 41비트, 5비트
21쪽
p.21IA-64 레지스터
  • 128개의 일반 목적 64비트 정수 레지스터
  • 128개의 일반 목적 64/80비트 부동소수점 레지스터
  • 64개의 1비트 predicate register(예측 레지스터)
  • GPR은 software pipelining(소프트웨어 파이프라인) 루프를 위해 코드 크기를 줄이기 위해 '회전'된다
  • 회전은 단순한 형태의 레지스터 이름 변경으로, 각 반복에서 한 명령어가 서로 다른 물리적 레지스터에 접근할 수 있게 한다
22쪽
p.22회전 레지스터 파일
  • 문제: 스케줄링된 루프는 많은 레지스터를 필요로 하며, 프롤로그 및 에필로그에 많은 중복 코드가 존재한다
  • 해결책: 각 루프 반복에 대해 새로운 레지스터 세트를 할당한다
23쪽
p.23회전 레지스터 파일
  • RRB=3
  • P0, P1, P2, P3, P4, P5, P6, P7
  • 회전 레지스터 기준(RRB) 레지스터는 현재 레지스터 세트의 기준을 가리킨다
  • 논리적 레지스터 식별자에 값이 더해져 물리적 레지스터 번호가 된다
  • 일반적으로 회전 레지스터와 비회전 레지스터로 나뉜다
24쪽
p.24회전 레지스터 파일
  • bloop
  • sd f9, ()
  • fadd f5, f4, ...
  • ld f1, ()
  • 3사이클 로드 지연은 레지스터 식별자 번호의 차이(예: f4 - f1 = 3)로 인코딩됨
  • 4사이클 fadd 지연은 레지스터 식별자 번호의 차이(예: f9 – f5 = 4)로 인코딩됨
  • bloop
  • sd P17, ()
  • fadd P13, P12,
  • ld P9, ()
  • RRB=8
  • bloop
  • sd P16, ()
  • fadd P12, P11,
  • ld P8, ()
  • RRB=7
  • bloop
  • sd P15, ()
  • fadd P11, P10,
  • ld P7, ()
  • RRB=6
  • bloop
  • sd P14, ()
  • fadd P10, P9,
  • ld P6, ()
  • RRB=5
  • bloop
  • sd P13, ()
  • fadd P9, P8,
  • ld P5, ()
  • RRB=4
  • bloop
  • sd P12, ()
  • fadd P8, P7,
  • ld P4, ()
  • RRB=3
  • bloop
  • sd P11, ()
  • fadd P7, P6,
  • ld P3, ()
  • RRB=2
  • bloop
  • sd P10, ()
  • fadd P6, P5,
  • ld P2, ()
  • RRB=1
  • 루프 종료 브랜치는 RRB를 감소시킨다
  • 이전 루프 예제 (루프 변환을 거친 경우)
  • 코드 크기 감소가 어떻게 이루어지는지 확인할 수 있음
25쪽
p.25IA-64 predicated execution(예측 실행)
  • 문제: 잘못 예측된 브랜치는 ILP를 제한한다
  • 해결책: predicated execution(예측 실행)을 통해 예측하기 어려운 브랜치를 제거한다
  • 거의 모든 IA-64 명령어는 predicate register(예측 레지스터)에 따라 조건부로 실행될 수 있다
  • predicate register(예측 레지스터)가 false이면 명령어는 노-오퍼레이션(NOP)이 된다
  • 네 개의 basic block(기본 블록)
  • Inst 1
  • Inst 2
  • br a==b, b2
  • Inst 3
  • Inst 4
  • br b3
  • Inst 5
  • Inst 6
  • Inst 7
  • Inst 8
  • b0:
  • b1:
  • b2:
  • b3:
  • if
  • else
  • then
  • predicated execution(예측 실행)
  • 한 개의 basic block(기본 블록)
  • Mahlke 등, ISCA95: 평균적으로 50% 이상의 브랜치 제거됨
  • 경고: 버스패싱을 복잡하게 만든다!
26쪽
p.26IA-64 speculative execution(추측 실행)
  • 문제: 브랜치는 컴파일러의 코드 이동을 제한한다
  • Inst 1
  • Inst 2
  • br a==b, b2
  • Load r1
  • Use r1
  • Inst 3
  • 브랜치 위로 로드를 이동할 수 없다
  • 왜냐하면 비정상적인 예외를 유발할 수 있기 때문이다
  • Load.s r1
  • Inst 1
  • Inst 2
  • br a==b, b2
  • Chk.s r1
  • Use r1
  • Inst 3
  • speculative load(추측 로드)는 예외를 유발하지 않지만
  • 목적 레지스터에 'poison bit(포이즌 비트)'를 설정한다
  • 원래 홈 블록에서 예외를 확인하고
  • 예외가 감지되면 수정 코드(fixup code)로 점프한다
  • 특히 긴 지연을 가진 로드를 조기에 스케줄링하는 데 유용하다
  • 해결책: 예외를 유발하지 않는 추측 연산
27쪽
p.27IA-64 data speculation(데이터 추측)
  • 문제: 가능한 메모리 위험은 코드 스케줄링을 제한한다
  • address check table(주소 체크 테이블)에 연관된 하드웨어가 필요하다
  • Inst 1
  • Inst 2
  • Store
  • Load r1
  • Use r1
  • Inst 3
  • 스토어가 같은 주소에 쓸 수 있으므로
  • 로드를 스토어 위로 이동할 수 없다
  • Load.a r1
  • Inst 1
  • Inst 2
  • Store
  • Load.c
  • Use r1
  • Inst 3
  • data speculation(데이터 추측) 로드는 주소를 address check table(주소 체크 테이블)에 추가한다
  • 스토어는 address check table(주소 체크 테이블) 내 일치하는 로드를 무효화한다
  • 로드가 무효화되었거나 누락되었는지 확인하고
  • 그럴 경우 수정 코드(fixup code)로 점프한다
  • 해결책: pointer hazard(포인터 위험)을 확인하는 하드웨어
28쪽
p.28static scheduling(정적 스케줄링)의 한계
  • statically unpredictable branches(정적 예측 불가 브랜치)
  • 변동 메모리 지연(예측 불가한 캐시 미스)
  • code size explosion(코드 크기 폭발)
  • 컴파일러 복잡성
  • 여러 시도에도 불구하고, VLIW는 일반 목적 컴퓨팅 분야에서 실패했다(지금까지)
  • 더 복잡한 VLIW 아키텍처는 순차 처리 superscalar(초순차 처리)와 복잡도가 비슷하며, 대규모 복잡한 애플리케이션에서 실질적인 이점이 없다
  • embedded DSP(임베디드 DSP) 시장에서는 성공했다
  • 환경이 제한된 더 단순한 VLIW, 코드 친화적
29쪽
p.29아이테니엄 2의 성능
  • 아이테니엄 2는 큰 다이 면적(421 mm²)을 가지며 더 많은 power consumption(전력 소비)를 한다
  • (Pentium 4는 die area(다이 면적)이 112 mm²)
  • SPECfp에서는 Power5보다 약간 느리고, Athlon 64 및 Pentium 4보다 약 35% 빠르다
  • SPECint에서는 Power5보다 약 15% 빠르고, Athlon 64 및 Pentium 4보다 약 15% 느리다
  • 1.5 GHz
  • 3.8 GHz
  • 2.8 GHz
  • 1.9 GHz
  • SPECfp
  • SPECint
30쪽
p.30아이테니엄의 종말
  • 한편, AMD는 자체 64비트 아키텍처인 AMD64를 출시했고, 이후 인텔도 이를 따라했다
  • 2017년, 인텔은 IA-64 프로세서의 최종 세대인 Kittson을 출시했다
  • 2019년, 인텔은 공식적으로 아이테니엄 CPU 제품군의 중단을 발표했다
31쪽
p.31
단축키
Ctrl K · s자료 검색
[ ]이전·다음 강의
Space영상 재생·정지
j k다음·이전 section
n p다음·이전 slide
b강의 목록 접기·펴기
t맨 위
/강의 검색
Esc닫기