미래로시스템고형호 hyungho.ko@gmail.com, http://hhko.tistory.com 2011.06.25( 토 ) 포스코센터서관 5 층
목차 2 1. ArBB 특징 2. ArBB 기초문법 3. ArBB 설치 4. 만델브로집합예제
3 1. ArBB 특징
벡터합구하기 배열 A a1 a2 a3 a4 a5 a6 a7 a8 배열 B b1 b2 b3 b4 b5 b6 b7 b8 배열 A 와배열 B 를더하여배열 C 에저장하라! C/C++ 구현 float A[SIZE], B[SIZE], C[SIZE]; for (int i = 0; i < SIZE; i++) C[i] = A[i] + B[i]; 4
두점간의거리구하기 다차원공간에서두점간의거리를구하시오. ( 유클리드거리, Euclidean distance) C/C++ 구현 5 double distance; double sum = 0; std::vector<double> X(SIZE), Y(SIZE); for(size_t i = 0; i < X.size(); ++i) sum += (X[i] Y[i]) * (X[i] Y[i]); distance = std::sqrt(sum);
데이터변경 float A[SIZE], B[SIZE], C[SIZE]; for (int i = 0; i < SIZE; i++) C[i] = A[i] + B[i]; double distance; double sum = 0; std::vector<double> X(SIZE), Y(SIZE); for(size_t i = 0; i < X.size(); ++i) sum += (X[i] Y[i]) * (X[i] Y[i]); distance = std::sqrt(sum); 데이터가 2 차원 (?) 일때 C/C++ 구현 몸과마음이아파요 ^^; 그러나알고리즘은변화하지않는다. 6
벡터합 / 유클리드거리 float A[SIZE], B[SIZE], C[SIZE]; for (int i = 0; i < SIZE; i++) C[i] = A[i] + B[i]; double distance; double sum = 0; std::vector<double> X(SIZE), Y(SIZE); for(size_t i = 0; i < X.size(); ++i) sum += (X[i] Y[i]) * (X[i] Y[i]); distance = std::sqrt(sum); 공통점 프로그래밍추상화 (abstraction) 수준이낮다. 연속적인데이터에대해서동일한연산이수행된다. 7
추상화 float A[SIZE], B[SIZE], C[SIZE]; for (int i = 0; i < SIZE; i++) C[i] = A[i] + B[i]; float A[SIZE], B[SIZE], C[SIZE]; C = A + B; double distance; double sum = 0; std::vector<double> X(SIZE), Y(SIZE); for(size_t i = 0; i < X.size(); ++i) sum += (X[i] Y[i]) * (X[i] Y[i]); distance = std::sqrt(sum); double distance; double sum = 0; std::vector<double> X(SIZE), Y(SIZE); sum = add_reduce((x Y) * (X Y)); distance = sqrt(sum); 8
Flynn 의병렬컴퓨터분류 SISD Single Instruction stream, Single Data stream 단일명령으로단일데이터처리 SIMD Single Instruction stream, Multiple Data stream 단일명령으로다중데이터처리 9 MISD MIMD Multiple Instruction stream, Single Data stream 다중명령으로단일데이터처리 Multiple Instruction stream, Multiple Data stream 다중명령으로다중데이터처리
벡터프로세싱 배열 A a0 a1 a2 a3 a4 a5 a6 a7 배열 B b0 b1 b2 b3 b4 b5 b6 b7 배열 A 와배열 B 를더하여배열 C 에저장하라! 사이클 1 a0 + b0 사이클 2 a1 + b1 사이클 3 사이클 4 사이클 5 사이클 6 사이클 7 a2 + b2 a3 + b3 a4 + b4 a5 + b5 a6 + b6 사이클 1 a0 + b0 a1 + b1 a2 + b2 a3 + b3 사이클 2 a4 + b4 a5 + b5 a6 + b6 a7 + b7 10 사이클 8 a7 + b7
CPU 와벡터프로세싱명령어셋발전사 연도 CPU CPU 확장명령어셋 벡터처리능력 ( 벡터레지스터수 ) 1996 1997 펜티엄 P55C MMX Multi Media extensions 64 비트 1998 1999 2000 2001 펜티엄 3 카트마이펜티엄 4 윌라멧 SSE Streaming SIMD Extensions 128 비트 SSE 2 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 펜티엄 4 프레스캇코어2 메롬코어2 펜린코어 i7 네할렘웨스트미어샌디브릿지 SSE 3 SSE 4 AVX Advanced Vector Extensions 256 비트 11 2013
데이터병렬성 float A[SIZE], B[SIZE], C[SIZE]; C = A + B; double distance; double sum = 0; std::vector<double> X(SIZE), Y(SIZE); sum = add_reduce((x Y) * (X Y)); distance = sqrt(sum); SIMD 적용 연속적인데이터에대해서동일한연산이동시적으로수행된다. 데이터병렬성 (Data Parallelism) 12
ArBB 필요성 float A[SIZE], B[SIZE], C[SIZE]; for (int i = 0; i < SIZE; i++) C[i] = A[i] + B[i]; double distance; double sum = 0; std::vector<double> X(SIZE), Y(SIZE); for(size_t i = 0; i < X.size(); ++i) sum += (X[i] Y[i]) * (X[i] Y[i]); distance = std::sqrt(sum); 개선 float A[SIZE], B[SIZE], C[SIZE]; C = A + B; double distance; double sum = 0; std::vector<double> X(SIZE), Y(SIZE); sum = add_reduce((x Y) * (X Y)); distance = sqrt(sum); 프로그래밍추상화 (abstraction) 수준이높다. 13 연속적인데이터에대해서동일한연산이동시적으로수행된다.
Array Building Blocks C89 표준준수 (C++, Python, ) Intel 제작 결정적 (Deterministic) 프로그래밍 ( 레이스컨디션과데드락없음 ) 하드웨어아키텍처독립 (CPU, Accelerator, ) 특징 일반 버전 1.0 ( 베타 ) 퓨전최적화 ( 벡터프로세싱 vs 스칼라프로세싱 ) ArBB 스레드추상화 (TBB: Threading Building Blocks) C++ 템플릿라이브러리 Intel C++ Compiler Visual Studio C++ Standard C++ Compiler 환경 Processor Intel AMD OS Windows Linux 14 GNU Compiler
15 2. ArBB 기초문법
스칼라타입 (scalar type) 1. C++ 과달리최적화된벡터프로세싱을위해명시적인데이터타입크기표시 i8, i16, i32, i64, f32, f64 2. 내부적으로템플릿클래스로구현 template<arbb_scalar_type_t scalar_type> class scalar; 3. C++ 기본타입과비교 타입 설명 유사 C++ 타입 f32, f64 32/64비트부동소수점수 float, double i8, i16, i32, i64 8/16/32비트부호가있는정수 char, short, int u8, u16, u32, u64 8/16/32비트부호가없는정수 unsigned char/short/int boolean 참 / 거짓값 (true 또는 false) bool usize, isize 플랫폼에의존적인부호가있거나없는정수 size_t 16
스칼라타입 (scalar type) // 8 비트정수 i8 value = 10; // 타입캐스팅 (i8 f32) f32 average = (f32)value; // 32 비트부동소수점수 f32 average = 1.345f; // 타입캐스팅 (ArBB C++) float f = (float)average; float f = value(average); // 타입캐스팅 (C++ ArBB) float f = 1.5f; f32 average = f; 17
컨테이너타입 (container type) 1. 스칼라타입의데이터로구성된벡터연산용컬렉션 2. 종류 1 정형컨테이너 : dense, array, 혼용 서로다른 class 또는 struct 객체들로구성 2 비정형컨테이너 : nested 18
arbb::dense 컨테이너타입 1. STL 의 vector 나 C++ 의배열에해당 2. dense 템플릿클래스의원형 : 원소타입과차원으로구성 template<typename T, std::size_t D = 1> class dense; 차수 D 는 1 에서 3 사이의값 명시하지않으면 1 로인식됨 19
arbb::dense 컨테이너타입 3. dense 컨테이너에대한연산 A. 모든스칼라연산들이원소별로적용될수있다 산술, 비트연산등 B. 컨테이너연산 인덱싱 : operator[] 순서변경 : shift(), section() 리덕션 : sum(), any(), all() 속성접근 : num_rows() C. 대부분의연산들은병렬로실행된다 예를들어, 두개의 dense 컨테이너를더하면각원소들은병렬로더해진다. 20
arbb::dense 컨테이너타입 4. 데이터접근법 A. 반복자를통한접근 1 read_only_range 2 write_only_range 3 read_write_range : 컨테이너에서값을읽는다 : 컨테이너에값을쓴다 : 읽기 / 쓰기모두가능 B. 바인딩을통한접근 바인딩 (binding) : 이미생성된특정데이터위치와컨테이너를연결 컨테이너와연결된데이터위치는서로데이터를주고받을수있다. 메모리 10 5 3 12 21 bind(arbb 컨테이너, 기존 C/C++ 데이터, Size);
제어흐름 1. 모든제어흐름은 _end 구문으로짝을이루어야한다 ( 예 : _while, _end_while). 2. ArBB의제어흐름구문은예약어가아니라매크로이다. 3. _for에대한인수들은세미콜론이아닌콤마로구분된다. 4. do/while 루프대신에 _do/_until 루프를사용한다. 5. switch와 goto는제공되지않는다. _for (i = 0, i < max_count, i++)... _end_for; ArBB 의제어흐름은 C++ 과달리다음과같은규칙을갖고있으므로 22 코드를작성할때유의해야한다.
_if 매크로 #define _if(cond) \ \ ARBB_CPP_NS::detail::if_stack().push(true); \ ARBB_CPP_NS::detail::if_stack().top().begin(cond); \ if (ARBB_CPP_NS::detail::capturing() \ ARBB_CPP_NS::detail::if_stack().top().if_value()) 23
ArBB 구현 float A[SIZE], B[SIZE], C[SIZE]; C = A + B; dense<f32> A, B, C; C = A + B; double distance; double sum; std::vector<double> X(SIZE), Y(SIZE); sum = add_reduce((x Y) * (X Y)); distance = sqrt(sum); f64 distance; f64 sum; dense<f64> X(SIZE), Y(SIZE); sum = add_reduce((x Y) * (X Y)); distance = sqrt(sum); 24
실행최적화 25 ARBB_OPT_LEVEL=O2 ARBB_OPT_LEVEL=O3
26 3. ArBB 설치
ArBB 홈페이지 http://software.intel.com/en-us/articles/intel-array-building-blocks/ ArBB 베타다운로드받기 27
Visual Studio 2010 통합 28 Add MSVC Debugger Integration
프로젝트속성 항목추가포함디렉터리추가라이브러리디렉터리추가종속성 모든구성 ( 디버그 / 릴리즈 ) 디버그모드 릴리즈모드 값 $(include) $(lib) 또는 $(LIBRARY_PATH) arbb_dev.lib arbb.lib 디버그 arbb_dev.lib 릴리즈 arbb.lib 29
30 4. 만델브로집합
만델브로집합정의 만델브로집합은브누아만델브로라는사람이창시한프랙탈기하학에서나온개념 다음과같은수열이발산하지않게하는복소수 c 의집합으로정의됨. 31
만델브로집합직렬코드 void DoIt() for (int x = 0; x< NUM_ROWS; x++) for (int y = 0; y< NUM_COLS; y++) rest[x][y] = Mandelbrot(std::complex(scale[x], scale[y]), MAX_COUNT); float Mandelbrot(std::complex c, int max_count) int count = 0; std::complex z = std::complex(0.f, 0.f); for (int k = 0; k <max_count; k++) if (abs(z) >= 2.f) break; z = z * z + c; count++; return (float)count; 32
만델브로집합 ArBB 코드 void DoIt()... arbb::call(mandelbrot)(c, dest); void Mandelbrot(dense<std::complex<f32>, 2> c, dense<f32, 2>& dest) arbb::map(mandelbrot_in_scalar)(c, dest); arbb::map 함수가컨테이너 (dense) 에있는개별데이터를자동으로전달시킨다. void Mandelbrot_in_Scalar(std::complex<f32> c, f32& rest) i32 count = 0; std::complex<f32> z = std::complex<f32> (0.f, 0.f); _for (i32 i = 0, i < MAX_COUNT, i++) _if (abs(z) >= 2.f) _break; _end_if; z = z * z + c; count++; _end_for; 33 rest = (f32)count;
만델브로집합실행결과 약 4 배의성능향상!!! (ARBB_OPT_LEVEL=O2) 약 14 배의성능향상!!! (ARBB_OPT_LEVEL=O3) 34