HPC에 적합한 처리를 실현하기 위해 인텔에서 만반의 준비를 해 등장한 인텔 Xeon Phi 코 프로세서. 경쟁 제품에 대한 프로그래밍의 용이성과 그 경쟁 제품에 필적하는 성능의 양립을 어필하고 있는 제품이지만, 실제 프로그래밍 작업이 어디까지 쉽게인지, 그리고 그 결과로서의 성능은 무엇인지 검증을 실시.
결과 Phi 용으로 컴파일을 다시하는 것 만으로 E5-2680 x 2CPU의 약 2 배, 내장 명령을 사용해 튜닝을 하면 약 7 ~ 9 배의 실효 성능.
제품이름 | HPC5000-XSPHI4R2S |
|
프로세서 | 인텔 제온 E5-2680 (8코어, 2.70GHz) x 2 CPU |
|
코프로세서 | 인텔 제온 파이 5110P x 2 |
|
메모리 | 16GB Registered ECC DDR3 1600MHz x 8 (총 128GB) |
|
OS | CentOS 6.3 x86_64 |
|
컴파일러 | intel C++ Composer XE 2013 Update 2 (icpc 13.1.0.146) |
|
MPI | intel MPI 라이브러리 4.1 |
|
컴파일 옵션 (Xeon E5) |
-ipo-O3-xHost-no-prec-div | |
컴파일 옵션 (Xeon Phi) |
-ipo-O3-mmic-no-prec-div |
프로그램
튜닝 전 N 형 문제 프로그램은 다음과 같다 (주요 부분 발췌).
template<typename T> struct vec3_t { T *x; T *y; T *z; }; template<typename T> static void update(int n, vec3_t<T> *newX, vec3_t<T> *oldX, T *m, vec3_t<T> v) { const T dt = (T) 0.016; const T eps = (T) 0.1; #pragma omp parallel for #pragma vector aligned #pragma ivdep for (int i = 0; i < n; ++i) { T xi = oldX->x[i]; T yi = oldX->y[i]; T zi = oldX->z[i]; T ax = (T) 0.0; T ay = (T) 0.0; T az = (T) 0.0; for (int j = 0; j < n; ++j) { T xj = oldX->x[j]; T yj = oldX->y[j]; T zj = oldX->z[j]; T rx = xj - xi; T ry = yj - yi; T rz = zj - zi; T r2 = rx * rx + ry * ry + rz * rz + eps; T r_r = (T) 1.0 / std::sqrt(r2); T r_r3 = r_r * r_r * r_r; T s = m[j] * r_r3; ax += rx * s; ay += ry * s; az += rz * s; } T vxi = v.x[i] + ax * dt; T vyi = v.y[i] + ay * dt; T vzi = v.z[i] + az * dt; xi += vxi * dt; yi += vyi * dt; zi += vzi * dt; newX->x[i] = xi; newX->y[i] = yi; newX->z[i] = zi; v.x[i] = vxi; v.y[i] = vyi; v.z[i] = vzi; } vec3_t<T> tmpX = *oldX; *oldX = *newX; *newX = tmpX; } |
[표 1.] 이 프로그램을 그대로 컴파일하고 실행하면 다음과 같은 성능
표1 미 튜닝시의 벤치마크 결과 (N = 65,536) | |||||
Xeon E5-2680 x 2 |
Xeon Phi 5110P x 1 |
고속화율 |
|||
단정밀도 | 164.836 Gflops |
313.188 GFlops |
1.9배 |
||
배정밀도 | 55.430 Gflops |
135.721 GFlops |
2.449배 |
인텔 Xeon Phi 코 프로세서에 최적화
인텔 MIC용 내장 명령을 사용한 소스 코드 예제 (단정밀도)
#include <micvec.h> template<> static void update<float> (int n, vec3_t<float> *newX, vec3_t<float> *oldX, float *m, vec3_t<float> v) { const __m512 dt = _mm512_set1_ps((float) 0.016); const __m512 eps = _mm512_set1_ps((float) 0.1); #pragma omp parallel for for (int i = 0; i < n; i += 16) { __m512 xi = _mm512_load_ps(oldX->x + i); __m512 yi = _mm512_load_ps(oldX->y + i); __m512 zi = _mm512_load_ps(oldX->z + i); __m512 ax = _mm512_setzero_ps(); __m512 ay = _mm512_setzero_ps(); __m512 az = _mm512_setzero_ps(); for (int j = 0; j < n; ++j) { __m512 xj = _mm512_set1_ps(oldX->x[j]); __m512 yj = _mm512_set1_ps(oldX->y[j]); __m512 zj = _mm512_set1_ps(oldX->z[j]); __m512 rx = _mm512_sub_ps(xj, xi); __m512 ry = _mm512_sub_ps(yj, yi); __m512 rz = _mm512_sub_ps(zj, zi); __m512 r2 = _mm512_fmadd_ps(rz, rz, _mm512_fmadd_ps(ry, ry, _mm512_fmadd_ps(rx, rx, eps))); __m512 r_r = _mm512_rsqrt23_ps(r2); __m512 r_r3 = _mm512_mul_ps(r_r, _mm512_mul_ps(r_r, r_r)); __m512 s = _mm512_mul_ps(_mm512_set1_ps(m[j]), r_r3); ax = _mm512_fmadd_ps(rx, s, ax); ay = _mm512_fmadd_ps(ry, s, ay); az = _mm512_fmadd_ps(rz, s, az); } __m512 vxi = _mm512_load_ps(v.x + i); __m512 vyi = _mm512_load_ps(v.y + i); __m512 vzi = _mm512_load_ps(v.z + i); vxi = _mm512_fmadd_ps(ax, dt, vxi); vyi = _mm512_fmadd_ps(ay, dt, vyi); vzi = _mm512_fmadd_ps(az, dt, vzi); xi = _mm512_fmadd_ps(vxi, dt, xi); yi = _mm512_fmadd_ps(vyi, dt, yi); zi = _mm512_fmadd_ps(vzi, dt, zi); _mm512_store_ps(newX->x + i, xi); _mm512_store_ps(newX->y + i, yi); _mm512_store_ps(newX->z + i, zi); _mm512_store_ps(v.x + i, vxi); _mm512_store_ps(v.y + i, vyi); _mm512_store_ps(v.z + i, vzi); } vec3_t<float> tmpX = *oldX; *oldX = *newX; *newX = tmpX; } |
인텔 MIC용 내장 명령을 사용한 소스 코드 예제 (배정밀도)
#include <micvec.h> template<> static void update<double> (int n, vec3_t<double> *newX, vec3_t<double> *oldX, double *m, vec3_t<double> v) { const __m512d dt = _mm512_set1_pd((double) 0.016); const __m512d eps = _mm512_set1_pd((double) 0.1); const __m512d c05 = _mm512_set1_pd((double) 0.5); const __m512d c15 = _mm512_set1_pd((double) 1.5); #pragma omp parallel for for (int i = 0; i < n; i += 8) { __m512d xi = _mm512_load_pd(oldX->x + i); __m512d yi = _mm512_load_pd(oldX->y + i); __m512d zi = _mm512_load_pd(oldX->z + i); __m512d ax = _mm512_setzero_pd(); __m512d ay = _mm512_setzero_pd(); __m512d az = _mm512_setzero_pd(); for (int j = 0; j < n; ++j) { __m512d xj = _mm512_set1_pd(oldX->x[j]); __m512d yj = _mm512_set1_pd(oldX->y[j]); __m512d zj = _mm512_set1_pd(oldX->z[j]); __m512d rx = _mm512_sub_pd(xj, xi); __m512d ry = _mm512_sub_pd(yj, yi); __m512d rz = _mm512_sub_pd(zj, zi); __m512d r2 = _mm512_fmadd_pd(rz, rz, _mm512_fmadd_pd(ry, ry, _mm512_fmadd_pd(rx, rx, eps))); __m512 r2_ps = _mm512_cvtpd_pslo(r2); __m512d r2_05 = _mm512_mul_pd(r2, c05); __m512 r_r_ps = _mm512_rsqrt23_ps(r2_ps); __m512d r_r = _mm512_cvtpslo_pd(r_r_ps); r_r = _mm512_mul_pd(r_r, _mm512_fnmadd_pd(_mm512_mul_pd(r2_05, r_r), r_r, c15)); r_r = _mm512_mul_pd(r_r, _mm512_fnmadd_pd(_mm512_mul_pd(r2_05, r_r), r_r, c15)); __m512d r_r3 = _mm512_mul_pd(r_r, _mm512_mul_pd(r_r, r_r)); __m512d s = _mm512_mul_pd(_mm512_set1_pd(m[j]), r_r3); ax = _mm512_fmadd_pd(rx, s, ax); ay = _mm512_fmadd_pd(ry, s, ay); az = _mm512_fmadd_pd(rz, s, az); } __m512d vxi = _mm512_load_pd(v.x + i); __m512d vyi = _mm512_load_pd(v.y + i); __m512d vzi = _mm512_load_pd(v.z + i); vxi = _mm512_fmadd_pd(ax, dt, vxi); vyi = _mm512_fmadd_pd(ay, dt, vyi); vzi = _mm512_fmadd_pd(az, dt, vzi); xi = _mm512_fmadd_pd(vxi, dt, xi); yi = _mm512_fmadd_pd(vyi, dt, yi); zi = _mm512_fmadd_pd(vzi, dt, zi); _mm512_store_pd(newX->x + i, xi); _mm512_store_pd(newX->y + i, yi); _mm512_store_pd(newX->z + i, zi); _mm512_store_pd(v.x + i, vxi); _mm512_store_pd(v.y + i, vyi); _mm512_store_pd(v.z + i, vzi); } vec3_t<double> tmpX = *oldX; *oldX = *newX; *newX = tmpX; } |
[표2] 인텔 MIC를 위한 기본 명령어 튜닝시의 벤치마크 결과
Xeon E5-2680 x 2 | Xeon Phi 5110Px1 |
수동벡터화 |
E5 대비 |
PHI 대비 |
||||
단정밀도 | 164.836 GFlops (표1 결과) |
313.188 GFlops (표1 결과) |
1138.728 GFlops | 6.908배 | 3.636배 |
|||
배정밀도 | 55.430 GFops (표1 결과) |
135.721 GFlops (표1 결과) |
510.918 GFlops |
9.217배 |
3.764배 |
2013년 4월 9일 테스트 결과 입니다.
[벤치리뷰] 인텔 제온 파이 5110P와 엔비디아 테슬라 K20 행렬 곱 실효 성능 비교
[분석정보] 매니코어 프로세서로 손바닥 슈퍼 컴퓨터를 실현
[분석정보] TOP500 슈퍼컴퓨터 순위 2013년 6월
[분석정보] 4만 8000개의 제온파이로 중국 톈허2 세계에서 가장 빠른 슈퍼 컴퓨터
[정보분석] 인텔 60코어 매니코어 "Xeon Phi" 정식발표
[분석정보] 인텔 슈퍼컴퓨터용 가속기 Xeon Phi 5110P 발표
[분석정보] Intel, HPC 전용 보조 프로세서 Xeon Phi 2013년 1월부터 일반용으로 출시
[분석정보] IDF 2012에서 주목한 한가지, 매니 코어 "Knights Corner"
[정보분석] 엔비디아 세계 최다 트렌지스터 칩 GK 110 공개
[정보분석] IDF 2011 Justin Rattner 기조연설 매니코어 시대가 다가옴 1/2부
[정보분석] IDF 2011 Justin Rattner 기조연설 매니코어 시대가 다가옴 2/2부
[정보분석] 같은 무렵에 시작된 Nehalem과 Larrabee와 Atom
[분석정보] Intel은 Larrabee 계획과 아키텍처를 어떻게 바꾸나?
[분석정보] 다시 처음부터 시작된 라라비 무엇이 문제였나?
[분석정보] 라라비 (Larrabee)의 비장의 카드 공유 가상 메모리
[분석정보] 인텔의 스칼라 CPU + 라라비의 이기종 CPU 비전
[분석정보] Larrabee는 SIMD와 MIMD의 균형 - Intel CTO가 말한다.
[정보분석](암달의 법칙) 2010년대 100 코어 CPU 시대를 향해서 달리는 CPU 제조사
[분석정보] GDC 2009 드디어 소프트 개발자 정보도 나온 "Larrabee"
[정보분석] Intel 힐스보로가 개발하는 CPU 아키텍처의 방향성
[정보분석] 팀스위니 미래의 게임 개발 기술. 소프트웨어 렌더링으로 회귀
[분석정보] 정식 발표된 라라비(Larrabee) 아키텍처
[아키텍처] 베일을 벗은 인텔 CPU & GPU 하이브리드 라라비(Larrabee)
[정보분석] 암달의 법칙(Amdahl's law)을 둘러싼 Intel과 AMD의 싸움
[정보분석] 모든 CPU는 멀티 스레드로, 명확하게 된 CPU의 방향
'벤치리뷰·뉴스·정보 > 리뷰·벤치·제품' 카테고리의 다른 글
[모바일 리뷰] ASUS Fonepad에 탑재된 스마트폰 Atom의 진실 (0) | 2013.04.24 |
---|---|
[벤치리뷰] 탐스 하드웨어 2013년 4월 게임용 CPU 등급 (0) | 2013.04.24 |
[게임벤치] Far Cry 3 벤치마크 모음 (0) | 2013.04.22 |
[벤치리뷰] 2013년 4월 VGA (GPU) 등급 (0) | 2013.04.19 |
[벤치리뷰] 모바일,서피스프로, 엔비디아 GPU 벤치 (0) | 2013.04.07 |
[벤치리뷰] x86 ARM 크로스 플렛폼 그래픽 벤치마크 (0) | 2013.04.04 |
[벤치리뷰] 인텔 제온 파이 5110P와 엔비디아 테슬라 K20 행렬 곱 실효 성능 비교 (0) | 2013.03.29 |
[벤치리뷰] 게임용 CPU 2013년 3월 (0) | 2013.03.21 |