8/04/2016

ARM Performance Libraries 및 Parallel Programming

ARM이 Version 이 변경이 되면서 부터 Multi Core가 지원이 되며, Core의 갯수가 증가되고, 도 GPU가 제공하면서,
성능이 많이 Upgrade되었지만, CPU의 Core의 갯수가 증가가 되었다고 많은 성능 향상이 되지 않는다고 생각한다.
어차피 Core를 연결하는 내부 Bus Clock은 CPU와 동일 할 것이며, 개별 Core 마다 L1 Cache를 가지고
있다고 하여, Main Core와 Sub Core와 통신 및 스케쥴링을 어떻게 해야 하는지 본인도 아직 잘 모르겠지만,
분명한 것은 코어가 증가한다고 해서 무조건 그 만큼의 성능은 나오지 않는다는 것이다.
한계는 이미 거의 정해져 있다고 보지만 어떻게 좀 더 성능향상을 할지가 궁금할 뿐이다.

앞으로 이부분에 대해서 좀 더 학습을 해보고, 각 개별 부분에 대해 자세히 알아본 후 추후 지속적으로 수정하겠다.

1. ARM Performance Libraries

ARM에서 제공하는 HPC(High Performance Computing)라는 Library와 Open Source를 제공하고 있다.
ARM에서 제공하는 것은 유료인것 같아, Open source만 알아 보자.

   https://developer.arm.com/hpc


2. ARM HPC Open source 

ARM에서 제공하는 성능 HPC Open Source Packages들이다.
  1. Compilers    
  2. MPI (Message Passing Interface)
  3. Maths libraries: 
  4. Utility programs
  5. Profiling tools
  6. Python packages

자세한 내용은 아래의 사이트에서 확인하자.
   https://developer.arm.com/hpc/hpc-software/hpc-software-subscription/hpc-open-source-packages

흥미로운것은 MPI 이며 이 부분을 어떻게 Programing할지도 관심이다.


2.1 Compilers 

MPI를 Compiler를 이용하여 Programing가능하며 일단 간단하게 각각의 Compiler를 알아보자.

  • Complier의 기본구조 
GCC or LLVM의 경우도 아래와 같은 구성으로 되어 있으며, Back End에 따라 Cross Compile로 되는지 설정이 된다.




  1.   Frontend: ( lexical analysis, Preprocessing, Syntax analysis 등 일을 한다고 한다) 
  2.   Middle end: IR 중간 Code를 생성
  3.   Back end: code generator  실제 실행 코드 및 optimization을 한다고 한다. 

Compiler 상위기본구조 
상위구조를 쉽게 이해하고자 하면 직접 GCC 크로스 컴파일러를 만들어 보면 된다. 
  https://en.wikipedia.org/wiki/Compiler
  http://blog.seulgi.kim/2014/11/compiler-structure-front-end-back-end.html


  • GCC 
ARM의 Version 변경이 되면서, FPU 지원 및  THUMB32를 지원하기 위해서, GCC에서도 이를 지원을 해주며, 
가장 보편적으로 많이 사용하는 Open Source Compiler이다.
GCC의 경우 오래전에는 직접 오픈소스를 받아 빌드하여 직접 크로스컴파일러를 구성해야했지만, 이제는 칩벤더 혹은 회사에서 
기본제공되어 쉽게 사용하기에도 사용하기도 편하고 메뉴얼은 GCC Manual을 보면 쉽게 자세히 알수 있다. 
물론 자세히 나와 있어 세부설정을 비롯하여 내부 Prefix된 명령어도 쉽게 익힐 수 있다.

  https://gcc.gnu.org/onlinedocs/
  https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/ARM-Options.html#ARM-Options


  • LLVM(Low-Level virtual machine)
GCC와 동일하게 컴파일 기능을 제공하며, Java의 JIT 처럼도 중간언어 기능인 비트코드를 지원가능 가능하며,성능 및 소스의 크기는 GCC보다 좋다고 한다.
현재 CLANG이라고, GCC 기반의 LLVM Compiler로 사용하려고 하고 있으며, 주로 iOS or OSX의 App에서 사용한다고 한다.

  https://ko.wikipedia.org/wiki/LLVM
  http://llvm.org/
  https://ko.wikipedia.org/wiki/%ED%81%B4%EB%9E%AD
  http://ji007.tistory.com/entry/LLVM-Low-Level-Virtual-Machine

  • IOS or OSX Apps Compiler 
  http://kyejusung.com/2015/11/llvm%EC%9D%B4%EB%9E%80-clang-%EB%B9%84%ED%8A%B8%EC%BD%94%EB%93%9C-%ED%8F%AC%ED%95%A8/

이외에도 ARM 전용 Compiler를 비롯하여 TI DSP 전용 Compiler가 존재하므로 각각의 Manual을 반드시 참조하자
특히 Linker Script 와 컴파일러 내부명령어는 컴파일러 마다 다르므로 반드시 Manual을 확인하자 


2.2 Interpreter 


  • Interpreter 기본설명 
가장 대표적인 Interpreter는 아마 Basic일 것이지만, 최근부터 많이 사용되어지는 Python은 사용하기도 쉽고 이해하기도 쉬어서 많이 사용되어진다.

세부설명아래참조
  https://ko.wikipedia.org/wiki/%EC%9D%B8%ED%84%B0%ED%94%84%EB%A6%AC%ED%84%B0
  https://en.wikipedia.org/wiki/Interpreter_(computing)

Python의 경우는 실행시간에 기본적인 Python Interpreter 동작하여 이미 Compile된 Library의 Symbolic Function을 연결하여 동작하는 방식과
내부 별도의 동작방식이 존재하는 것 같다 ( 이부분 별도로 좀 더 알아봐야겠다)

주의해야할 것은 예상하지 못한 Run Time 에러의 문제일 것이며, Script 언어로만 사용되어지기보다
많이 확장이되어 사용되어지므로 많이 알아봐가면서 공부를 해야 할 것 같다. 

  • Python ( MPI 사용)
  http://materials.jeremybejarano.com/MPIwithPython/


3. Parallel Programming 

  • Multicore 관련자료 링크  
  https://en.wikipedia.org/wiki/Multi-core_processor
  http://elinux.org/images/4/43/Understanding_And_Using_SMP_Multicore_Processors_Anderson.pdf
  http://www.springer.com/cda/content/document/cda_downloaddocument/9781441997388-c2.pdf?SGWID=0-0-45-1154842-p174106775


  • ARM의 Multi Core 이해 
현재 ARM은 효과적인 저전력모드를 제공하기 위해서 Multi Core들을 Big Group 과 Little Group으로 성능차이에 따라 두개의 Multi Core 그룹으로 운영하고 있다.
그리고 칩벤더에 따라 구성은 다 달라지는 것 같으며, 운영방식은 각 SoC or AP를 봐야 할 것 같다.

  • Homogeneous vs. heterogeneous multicore
  1. Homogeneous multicore systems: 동일의 architecture 를 공유하며 사용하며 1개 이상의 Core가 구성   
  2. Heterogeneous multicore systems: 다종의 architecture 를 1개 이상의 Core가 구성    

HMP(Heterogeneous Multi-Processing) 관련내용
  https://en.wikipedia.org/wiki/Heterogeneous_computing


  • Symmetric vs. asymmetric multiprocessing
  1. SMP(symmetric multiprocessing): one kernel, multiple cores
  2. AMP(asymmetric multiprocessing): multiple kernel, multiple cores (아직 사용된것을 못봄)
흔히 대칭형과 비대칭형 이라고 하며, SMP 방식의 경우 Linux에서 많이 채용되어 사용되어진다. 
  https://www.nxp.com/company/blog/three-reasons-why-embedded-heterogeneous-systems-are-more-efficient:BL-3-REASONS-EMBEDDED-SYSTEMS-EFFICIENT

SMP(symmetric multiprocessing)
  https://en.wikipedia.org/wiki/Symmetric_multiprocessing


  • ARM의 Big Little 의 다양한구조 
  https://en.wikipedia.org/wiki/ARM_big.LITTLE
  https://ko.wikipedia.org/wiki/Big.LITTLE

더불어 최근 Exynos를 보면 HMP(Heterogeneous Multi-core Processing) 기능을 제공하고 있다.
HMP는 기능을 살펴보면 ARM의 Little Group 과 Big Group은 동시에 사용을 하는 기능으로 보인다.



3.1 MPI(Message Passing Interface) or OpenMPI 

분산화 시스템에서 Parallel Programming 할 경우 MPI(Message Passing Interface) 사용하는 시스템이다.
대체적으로  여러 CPU과 RAM들과 통신하는 Interface이기에 분산화 시스템에서 많이 사용되어지는 것으로 보인다.
기본적으로 단위를 프로세스 단위로 구성하여 동작을 한다고 하며, 현재 Linux에서 지원을 하고 있다.
이와 관련된 프로그래밍은 별도로 Interface를 학습하고 해야할 것 같다.

  • 기본사용법
위 MPI or MP Library를 설치 후 원하는 App에 이에 맞게  Parallel Programming 하여 사용하는 것 같으며
기본적으로 개별 Parallel Programming 하는 Example과 동작원리를 세부적으로 봐야 알겠다.

솔직히 Parallel Programming을 직접 구성하여 사용해 본적이 없는 이에게 사용하기기 힘들것 같으며,
나도 역시 이를 가지고 아직 최적화하기에는 역부족인것 같다.



  • OpenMPI 설치 
  http://datamining.dongguk.ac.kr/wiki/index.php/Openmpi
  https://askubuntu.com/questions/25664/which-mpi-package-should-i-install

  • MPI Programing  (Open MPI API 사용)
  https://www.dartmouth.edu/~rc/classes/intro_mpi/hello_world_ex.html
  http://hamilton.nuigalway.ie/teaching/AOS/NINE/mpi-first-examples.html

  • How to Use Open MPI or MPICH
  http://www.linux-mag.com/id/5759/#install-openmpi
  http://ympahk.blogspot.kr/2014/05/openmpi.html
  https://sourcedexter.com/category/raspberry-pi-2/


  • OpenMPI Compiler
  http://manpages.ubuntu.com/manpages/trusty/man1/mpicc.openmpi.1.html

현재 Python과도 같이 연동이 되며, 이를 Parallel Programming 즉 분산화를 하기위해서는 OpenMPI API 를 별도로 알아야 하며 동작방식을 익혀야한다.

  • MPI 기본개념 관련부분 링크 
  https://en.wikipedia.org/wiki/Message_Passing_Interface
  https://computing.llnl.gov/tutorials/mpi/
  http://www.mcs.anl.gov/research/projects/mpi/tutorial/mpiintro/ppframe.htm
  http://www.mcs.anl.gov/research/projects/mpi/


3.2 OpenMP(Multi Processing)

동일하게 Parallel Programming에서 사용되어지는 방법으로 OpenMPI or MPI와 다르게 OpenMP는 여러 CPU와 보통 1개 RAM이 공유하여
Parallel Programming을 하는 Interface이다.
개인적으로 봐도 실제 Parallel Programming은 Open MP가 더 가까울 것 같으며, 이것으로도 최적화를 할 수 있을 것 같다.

  • OpenMP
위에서 설명했듯이 , Multi Core와 RAM이 공유하는 Parallel Programming으로 최신 ARM Version의 Multicore를 지원하는 System에서 
필요한 Parallel Programming인 것 같으며,ARM을 위한 부분은 별도로 찾아봐야 할 것 같다.
최신 ARM은  Heterogeneous Multi-core Processing (HMP) 지원되는 부분은 이것을 사용하는지는 알아봐야 할 것 같다.

  https://ko.wikipedia.org/wiki/OpenMP
  https://developer.arm.com/open-source

  • OpenMP 설치 
  https://askubuntu.com/questions/144352/how-can-i-install-openmp-in-ubuntu


  • OpenMP의 예제 
  https://minimonk.net/3534

  • OpenMP 와 MPI와 차이점 
둘다  Parallel Programming 용 Open Source를 제공하고  OpenMPI는 CPU와 RAM이 독자적으로  있는 시스템으로 분산시스템 (클러스터링)에  
주로  사용이 되는 Parallel Programming 인 것 같으며, 기본단위는 프로세스로 진행을 한다고 한다. 
더불어 OpenMP와 같이 메모리공유는 하지 않고 직접 Message 방식으로 통신을 하며 처리를 한다.
예를들면 슈퍼컴퓨터 같은것이 될 것 같다 ( 다중의 CPU와 다중의 Memory 기반 통신)

OpenMP인 경우는 Multi Core에 RAM은 공유를 한다고 하며, 기본적으로 Thread기반으로 사용을 하는것 같다

   http://askubuntu.com/questions/145119/what-is-the-difference-mpi-vs-openmp
   https://www.quora.com/What-is-the-difference-between-OpenMP-and-Open-MPI


3.3 OpenCL(Open Computing Language)

Parallel Programming의 한 종류로 주로 CPU 와 GPU와 함께 Parallel Programming 하기 위하여 만든 Interface 이다.
그래서 지원되는 것을 살펴보면 Graphic 회사들이 지원을 하고 있다.
상위의 OpenMP와 유사하지만 다만 Core가 GPU를 사용한다는 것이며, Programming하는 방식 역시 다르다.

일반적인 PC Based 구성
  http://johnwang3.blogspot.com/2015/02/zz-system-address-map-initialization-in_12.html

만약 PC Base라고 한다면 Embedded의 AP와 SoC와 다르게 GPU와 CPU는 PCIe로 연결되어 Bus기반으로 통신을 할 것이며, 
I/O Mapped IO 방식으로 구성이 되어 있어 GPU와 CPU의 메모리공유는 거의 힘들다고 본다.
PC에서 ARM으로 변경하면 ARM 내부버스는 AMBA의 AHB/APB Bus를 사용하겠으며 PC와 다르게 GPU와 CPU의 Memory 공유되며,
Memory Mapped IO 방식으로 쉽게 다른 주변기기도 공유가능 

대부분 Graphic Interface( Intel or NVIDIA)에서 SDK를 제공하고 있으며, 관련부분은 제조 Graphic Card사의 SDK를 세부적으로 봐야 알 것 같다. 
다만 NVIDIA는 기존에 CUDA가 존재하기 때문에 이 부분은 별도로 봐야 할 것 같다.


  • 기타 관련 참고 링크 및 관련자료 수집
추후에 시간이 되며 아래링크들을 좀 더 보고 알아보도록 하자

OpenCL
   https://developer.arm.com/products/software-development-tools/graphics-development-tools/mali-graphics-debugger

Computer Vision
  https://community.arm.com/graphics/b/blog/posts/arm-compute-library-for-computer-vision-and-machine-learning-now-publicly-available

Mali OpenCL SDK
   https://developer.arm.com/products/software/mali-sdks/mali-opencl-sdk

OpenCL 과 OpenGL ES
   https://developer.arm.com/docs/dto0038/b/1-introduction/13-software-development
   https://developer.arm.com/products/software-development-tools/graphics-development-tools

Mali GPU Driver
   https://developer.arm.com/products/software/mali-gpu-drivers

OpenCL
   https://ko.wikipedia.org/wiki/OpenCL
   https://en.wikipedia.org/wiki/OpenCL
   http://www.cc.gatech.edu/~vetter/keeneland/tutorial-2011-04-14/06-intro_to_opencl.pdf
   http://www.cmsoft.com.br/opencl-tutorial/advanced-aspects-c99-opencl-language/
   https://wiki.tiker.net/OpenCLHowTo

Cuda vs OpenCL
   https://wiki.tiker.net/CudaVsOpenCL