Translate

2021년 10월 3일 일요일

5장. 임의 정밀도 형(Arbitrary Precision Type)

 5장. 임의 정밀도 형(Arbitrary Precision Type)

    개요
    C++의 템플릿(template)
    실습 1. 부동소숫점 자료형으로 합성
    실습 2: 임의 정밀도 자료형으로 합성

-----------------------------------------------------------------------------------------------------


개요

레지스터 전송 수준, RTL(Register Transfer Level) 하드웨어 기술(hardware description)의 특징을 들자면 동작은 클럭 상세(clock-wise detail), 자료는 비트 상세(bit-wise detail)라 하겠다. 이번에 다룰 내용은 자료다. 고수준 언어 C/C++ 에서 자료의 기본형은 8비트를 한 바이트로 규정하고 그 배수 단위 비트 폭을 가진다. 아울러 자료 내부의 비트마다 의미를 부여한다. 정수는 최상위 비트를 부호를 표시하는 용도로 사용한다. 필요에 따라 양수 정수만을 취급하는 경우 부호비트는 의미없다. 32 비트 폭을 가진 부동 소수점 자료형의 비트 맵(bit-map)은 더 복잡하다. 가수(mantissa) 표시 영역과 지수(exponent) 영역으로 구분되어 있다. 물론 각 영역에 따로 부호를 가진다. 이러한 자료형의 기본 정의는 언어 규범 LRM에 명시되어 있다. 자료의 비트맵 구성이 복잡한 만큼 연산에 많은 수고가 든다. 이 수고로움이 하드웨어에로 옮겨지면 더 많은 클럭소요와 자원을 필요로 한다. 행렬 곱셈이 주를 이루는 디지털 신호처리 DSP, 인공지능 AI에 적용되는 알고리즘 들은 엄청난 량의 곱셈을 포함하기 때문에 전용의 하드웨어를 요구한다. DSP 전용 CPU, 벡터 곱셈에 동원된 GPU 들이 있다. 이런 고정된 하드웨어는 표준화된 자료형을 그대로 받아들이면서도 엄청난 속도를 자랑한다. 전력 소모량도 엄청나다. 전용 하드웨어 라면 응용에서 요구되는 정밀도에 맞게 자료형을 임의로 정함으로써 자원을 효과적으로 쓰면서 높은 성능을 기대할 수 있다. 하드웨어 사용량과 클럭 소요량은 하드웨어 제작 비용 뿐만 아니라 결국 저전력으로 이어진다.

C++의 템플릿(template)

C++ 언어로 추상성이 높아 지면서 도입된 객체지향 개념으로 크래스 (class)와 템플릿(template)이다. 크래스는 C의 구조체(structure)를 확장했다. 구조체는 한 객체를 나타내는데 쓰이는 자료를 한데 묶어 대변한다. 자료만을 모아두는 용기(container)에서 자료를 다루는 방법(함수와 연산자)까지 모아둔 용기가 크래스다. 템플릿은 객체의 형(type)을 확장한다. C에서 typedef 로 복합성분 객체를 다루기 위해 자료형을 정의할 수 있다. 구조체에 대해 새로운 자료형을 정의할 때 쓰인다면 템플릿은 크래스에 자료형을 정의한다. C++의 템플릿을 사전에서 찾아보면 다음과 같이 설명한다.

"함수나 클래스가 개별적으로 다시 작성하지 않고도 각기 다른 수많은 자료형에서 동작할 수 있게 한다."[...]

위의 설명에서 "다시 작성하지 않고"라는 표현에 주목하자. 크래스의 재사용성(re-usability)을 강조한 것이다. 템플릿은 RTL을 목표하는 HLS 에서 객체 선언에 가장 적극적으로 활용 된다.

C/C++ 고유 자료형(native data-type)은 char, short, long, float, double 등 몇 가지로 한정되고 이 자료형을 다루는 사칙 연산자도 대수학을 근거로 미리 준비되어 있다. RTL/HDL에서 자료형의 기본은 비트(bit)다. 2진수의 한자리 가지고는 연산이라고 정의하고 말 것도 없다. RTL에서 자료는 임의의 비트 폭(bit-width)으로 확장될 수 있다. 그 때마다 새로운 자료형을 정의하고 형변환 방법(type-conversion method)과 연산자(operator)를 만들려면 한도 끝도 없다. 그래서 템플릿을 활용한다. 예를 들어 임의 비트 폭을 갖는 정수는 다음과 같이 선언한다.

sc_int<W>  MyData;

기본형으로 sc_int 라는 크래스가 만들어져 있고 비트 폭은 템플릿으로 정한다. 두개의 마주보는 꺽쇠 <> 가 템플릿 이다. 0보다 큰 정수 W는 비트폭이다.

정수형 자료의 숫자의 표현 범위는 비트 폭으로 결정되고 정밀도는 최하위 비트의 변화량이다. 하지만 실수(real number)는 이보다 좀더 복잡하다. 고수준 언어에서 다루는 단정도 실수는 32비트 폭을 가지며 비트 위치와 범위가 갖는 의미는 IEEE 754 표준으로 정해져 있다. [...] 지수(exponent)와 가수(mantissa) 부분으로 나뉜다. 소숫점 위치는 고정되어 있지 않고 지수 부의 값에 의해 결정된다. 소숫점 위치가 떠다니므로(floating-point) C 언어에서 선언형을 float 라고 한다.

응용 전용의 하드웨어라면 처리하기 복잡하고 자원도 많이 쓰는 부동 소숫점 자료형을 일률적으로 사용할 필요는 없다. 소숫점의 위치를 고정시킨(fixed-point) 임의 정밀도 자료형을 활용한다. 고정 소수점 임의 정밀도 실수의 선언 방법은 다음과 같다.

sc_fixed<W, IW> MyData;

자료의 총 비트 폭은 W이며 그중 정수 부분이 차지하는 비트 범위는 상위 IW 만큼이다. 실제로 다음과 같이 선언된 실수는 총 8 비트 폭을 가지며 그중 소숫점 이상으로 5비트[-16 ~ +15], 소숫점 이하로 3비트 [0.0 ~ 0.875] 범위내의 수를 표현 할 수 있다. 총 표현 범위는 [-16.875 ~ 15.875]이며 정밀도는 0.125(=2^-3) 다. 비트 맵 형식이 정해져 있는 표준 부동 소숫점 형과는 달리 자릿수 비트폭을 늘리면 정밀도도 증가한다. 용도에 맞게 임의로 정밀도를 결정 할 수 있다. 

sc_fixed<8, 5> MyData;


-----------------------------------------------------------------------------------------------------


실습 1. 부동소숫점 자료형으로 합성

예제는 C++ 로 기술한 윈도우 함수(window function)다[...]. C++의 템플릿을 활용해 네가지 윈도우를 한개의 함수에 담았고 입출력 자료형을 선택할 수 있도록 했다.

윈도우 계수 롬(coefficient ROM)에 값을 채우기 위해 초기화 함수 init_coef_tab()을 호출한다. 이 함수에서 사용할 자료형들은 모두 템플릿을 통해 전달된다.

위에서 정의한 템플릿 크래스로 객체를 생성(선언)하고(instantiate class object) 크래스 멤버 함수 apply()를 호출하여 입력 데이터에 윈도우를 씌우는 계산을 수행한다.

예제를 합성해 보자. 입출력 자료형이 C/C++ 고유의 부동 소숫점 float 임에 유의 하자.

합성 보고서를 보면 생각보다 큰 자원을 쓰진 않았으나 부동 소숫점 곱셈을 위해 DSP에 특화된 자원이 사용 되었다. 내부 윈도우 계수표는 읽기용 메모리(ROM)으로 합성 되었다. 부동소숫점 연산기가 복잡하고 매우 특별한 설계자산(IP, intellectual property)으로 취급되는 만큼 RTL/HDL 소스로 제공 되지 않는다. 블랙박스 처리된 대신 자사 IP 생성용 tcl 스크립트가 제공 되었다. 외부 시뮬레이터(SystemC 와 ModelSim)으로 Co-Simulation은 불가하다.

-----------------------------------------------------------------------------------------------------


실습 2: 임의 정밀도 자료형으로 합성 [소스 다운로드]

윈도우 함수 C++ 설계에서 자료형을 float에서 임의 정밀도(arbitrary precision) 고정 소숫점(fixed point) 자료형으로 바꿨다. 입력과 출력 그리고 계수의 자료형이 각각 다르다. 입력은 8비트 정수(AD 샘플값이라고 하자), 18비트의 윈도우 계수는 정수부로 부호를 포함해 2비트이며 16비트를 소숫점 이하 값으로 쓴다. 윈도우 계수는 삼각함수에서 얻은 [-1.0:1.0] 사이의 값을 갖는다.

고급의 수학적 계산(초월함수)이 포함된 알고리즘을 하드웨어로 구현하는 경우 실수 연산의 부담을 피하기 위해 스케일 업(scale up)을 수행 하여 정수부 만을 따오기도 한다. 이를 위해 알고리즘에 손을 대야 한다. 알고리즘 개발자와 구현자가 동일인 인 경우는 흔치 않다. 구현자는 알고리즘을 속속들이 이해 했을까? 알고리즘을 하드웨어로 구현하는 과정에서 오류가 끼어들 여지가 다분하다. 심지어 수학적 기준(수렴성을 해치거나 계산 오버플로우 발생)을 벋어날 우려가 있다. 따라서 가급적 원 알고리즘을 최대한 변경하지 않으려면 스케일 업/다운 같은 자료(data)를 조작하기 보다 자료형(type)을 변경하는 쪽을 택하는 편이 오류로부터 안전하다. 물론 자료형의 변경에 따르는 오차는 평가분석 되어야 한다.

시뮬레이션으로 C 의 부동소숫점과 고정 소숫점 자료형의 변화로 인한 오차를 측정해 보자. 두 자료형 사이에 계산 오차가 존재한다. 결과는 허용 오차 범위로 잡은 0.001 이내로 들어 왔다. 허용 오차범위는 응용 시스템의 조건에 따라 달라질 것이다. 이 조건을 벋어 난다면 소숫점의 비트폭 범위를 늘려 정밀도를 높여야 한다.

응용에서 요구하는 허용 조건을 만족하는 형식의 고정 소숫점 자료형을 확정 하고 HLS 합성하였다. 합성 보고서를 보면 인터벌은 비슷하지만 하드웨어 자원 사용량이 눈에띄게 줄었다. 

설계 분석(Design Analysis)표를 통해 두 곱셈이 전체 계산에서 차지하는 비중을 살펴보자. 고정 소숫점 곱셈에 소요되는 클럭은 부동 소숫점 곱셈과 비교해 보면 큰 차이를 볼 수 있다.

이제 HLS로 생성된 RTL/HDL을 고정 소숫점 C 모델과 비교 검증해 본다. RTL/HDL-C++ Co-Simulation SystemC 테스트벤치 구성은 다음과 같다.

RTL/HDL의 출력은 24비트 2진수다. 이를 확인 하기위해 일일이 수작업으로 sc_fixed<24, 8>형식의 실수로 변환 할 수는 없는 노릇이다. RTL 시뮬레이션의 파형은 디버깅시 유용하나 입출력을 일일이 대조해가며 확인하는 것은 불가능 하다. 고정 소숫점 형식이 하드웨어 합성에 유용하긴 하나 검증 편의를 위해 모든 경우에 대해 형변환 방법을 제공 하지 않는다. 2진수 벡터를 보기 편한 실수로 변환해 주는 방법을 제공하지 않기 때문에 필요에 따라 형변환 함수를 별도로 만들어 주어야 한다. 이러한 별도의 기능 추가는 C/C++ 기반의 테스트 환경 이기에 수월하다.

임의로 정밀도를 결정 할 수 있는 고정 소숫점 자료형의 사용은 알고리즘을 하드웨어로 구현할 때 매우 유용하다. 단, 임의로 정해졌다는 점에 유의해야 한다. 표준 고급 컴퓨팅 언어의 부동 소숫점 자료형 float 은 표준화 되어 있으므로 모든 사용자(연구자, 개발자)들에게 설명이 필요 없다. 이에 반해 임의 정밀도 자료형은 소숫점의 위치가 임의로 주어 졌으므로 이에 대한 설명이 반드시 뒤따라야 하며 형변환 방법(함수)가 제공 되어야 한다. 위의 예에서 RTL/DHL 출력은 24비트 2진수 값이다. 별도의 설명이 없다면 소숫점이 어디에 위치 하는지 알 수 없다. 문서화된 설명서도 좋지만 기계가 읽을 수 있도록 형변환 함수를 제공하여 인간개입 오류를 예방 한다. 2진수 비트 벡터를 임의 정밀도 고정 소숫점 자료형으로 변환하는 함수는 다음과 같다.

 

---------------------------------------------------------------------------------
고위 합성 튜토리얼(High-Level Synthesis Tutorial)
[목차][이전][다음]


댓글 없음:

댓글 쓰기