<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2676526535909912629</id><updated>2012-02-16T05:53:19.074-08:00</updated><category term='멀티코어'/><category term='알고리즘'/><title type='text'>yhpdoit 블로그 - Programming</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://yhpdoit-programming.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2676526535909912629/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://yhpdoit-programming.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>yhpdoit</name><uri>http://www.blogger.com/profile/10307760148110502844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>1</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2676526535909912629.post-7391603804357182877</id><published>2009-06-23T19:05:00.000-07:00</published><updated>2011-03-26T11:57:20.919-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='멀티코어'/><category scheme='http://www.blogger.com/atom/ns#' term='알고리즘'/><title type='text'>[펌]Processor VS Algorithm</title><content type='html'>원본글 위치  : http://worldawesome.tistory.com/1&lt;br /&gt;저작자 : 고구마 장수&lt;br /&gt;&lt;fieldset style="margin: 20px 0px; padding: 5px;"&gt;&lt;legend&gt;&lt;span&gt;&lt;strong&gt;크리에이티브 커먼즈 라이선스&lt;/strong&gt;&lt;/span&gt;&lt;/legend&gt;&lt;!--Creative Commons License--&gt;&lt;div style="float: left; width: 88px; margin-top: 3px;"&gt;&lt;a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.0/kr/" target="_blank"&gt;&lt;img alt="Creative Commons License" style="border-width: 0pt;" src="http://i.creativecommons.org/l/by-nc-sa/2.0/kr/88x31.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="margin-left: 92px; margin-top: 3px; text-align: justify;"&gt;이 저작물은 &lt;a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/2.0/kr/" target="_blank"&gt;크리에이티브 커먼즈 코리아 저작자표시-비영리-동일조건변경허락 2.0 대한민국 라이선스&lt;/a&gt;에 따라 이용하실 수 있습니다&lt;/div&gt;&lt;/fieldset&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 18pt; color: rgb(0, 0, 0);"&gt;&lt;span style="font-size: 14pt;"&gt;&lt;span style="font-size: 11pt;"&gt;요즘 간만에  Software tuning의 세계에 빠져봅니다. 뭐 회사일로 바쁜 거지만 그 덕에 뭔가 배울 수 있는 것들이 늘어서 좋습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;  &lt;span style="font-size: 18pt; color: rgb(0, 0, 0);"&gt;&lt;span style="font-size: 14pt;"&gt;&lt;span style="font-size: 11pt;"&gt;Dual Core CPU가 요즘 화제지요? CPU의 내부 core가 쌍으로 있기 때문에 한개의 칩으로 두개의 CPU를 가지고 있으니 얼마나 편하겠어요. 하지만 사람들이 착각하고 있는 것이 있습니다. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);"&gt;&lt;span style="font-size: 18pt;"&gt;&lt;span style="font-size: 14pt;"&gt;&lt;span style="font-size: 11pt;"&gt;CPU가 두개라고 처리속도가 두배가 되지 않는 다는 사실입니다. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;   &lt;span style="font-size: 18pt; color: rgb(0, 0, 0);"&gt;&lt;span style="font-size: 14pt;"&gt;&lt;span style="font-size: 11pt;"&gt;&lt;span style="font-size: 11pt;"&gt;이게 무슨 소리냐고요? 자 한번 생각해봅시다. 아래와 같은  for loop가&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span style="font-size: 18pt; color: rgb(0, 0, 0);"&gt;&lt;span style="font-size: 14pt;"&gt;&lt;span style="font-size: 11pt;"&gt;&lt;span style="font-size: 11pt;"&gt;있다고 해봅시다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border: 1px solid rgb(121, 165, 228); padding: 10px; background-color: rgb(219, 232, 251);" class="txc-textbox"&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;for(int i=0; i&amp;lt;10000; i++)&lt;/span&gt; &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;{&lt;/span&gt; &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;    func(i);&lt;/span&gt; &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;}&lt;/span&gt; &lt;/div&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0); font-weight: bold;"&gt;code 1. Sequential code.&lt;/span&gt;  &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;이 프로그램이 수행되는 것은 일반적으로 θ(n)의 복잡도를 지닙니다. 이런&lt;/span&gt; &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;프로그램을 Compiler는 '순차적'으로 수행하게 됩니다. &lt;span style="background-color: rgb(184, 214, 61);"&gt;한데 두개의 CPU가 &lt;/span&gt;&lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0); background-color: rgb(184, 214, 61);"&gt;있을 때는 어떻게 될까요? OS가 나눠서 다 알아서 해줄까요? 그렇게 해주는 &lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;&lt;span style="background-color: rgb(184, 214, 61);"&gt;OS... 없습니다!!! &lt;/span&gt;만약 Dual CPU나 Dual-Core CPU에서 이렇게  &lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;짠 프로그램을 돌려보세요. Single CPU빠른거 하나 끼우는게 더 이익이 &lt;/span&gt; &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;됩니다. &lt;/span&gt;  &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;그럼 어떻게 해야 될까요? 바로 Parallelization을 해야 합니다. 위의 &lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;코드는 이렇게 하면 되겠군요. &lt;/span&gt;  &lt;div style="border: 1px solid rgb(121, 165, 228); padding: 10px; background-color: rgb(219, 232, 251);" class="txc-textbox"&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;#pragma omp parallel for&lt;/span&gt; &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;for(int i=0; i&amp;lt;10000; i++)&lt;/span&gt; &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;{&lt;/span&gt; &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;    func(i);&lt;/span&gt; &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;}&lt;/span&gt; &lt;/div&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0); font-weight: bold;"&gt;code 2. Parallelized code by OpenMP.&lt;/span&gt;  &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;헉!! 이게 뭡니까? 이상한 Precompiler header가 붙어 있지요? 이것은  &lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;OpenMP라는 Multi Parallelization을 지원하기 위한 표준기능입니다. 이렇게 &lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;하면 저 for문을 몇개의 Thread로 나눠서 병렬처리를 해줍니다. 물론 &lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;저렇게만 다 쓰면 되는 것도 아니겠지요? Compiler가 이 OpenMP를 지원&lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;해야 되겠지요. 이것은 Intel C++ Compiler나 Visual Studio 2005/2008에서 지원&lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;하고 있습니다. &lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;지금은 대부분의 Compiler들이 OpenMP를 지원해 주는 덕에 많이 편해졌습니다.  &lt;/span&gt; &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;실제 얼마나 향상이 될까요? 제가 Test해본바로는 Single core CPU에서는 &lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;OpenMP를 이용하더라도 전혀 속도의 효과를 보지 못했습니다. 하지만  &lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;Dual-core혹은 Dual CPU를 이용하면 두배 이상 빠른 것을 확인했습니다. &lt;/span&gt;  &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;이와 같이 CPU core의 숫자와 Parallelization code와는 수학적인 &lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;관계가 있습니다. 이것이 바로 &lt;span style="font-weight: bold;"&gt;Amdhal's law&lt;/span&gt;이고 다음과 같이 써집니다. &lt;/span&gt;&lt;br /&gt;&lt;div style="border: 1px solid rgb(121, 165, 228); padding: 10px; background-color: rgb(219, 232, 251);" class="txc-textbox"&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0); font-weight: bold;"&gt;&lt;span style="font-size: 18pt;"&gt;M = 1/ {  F + (1-F)*N }&lt;/span&gt;&lt;/span&gt; &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;  &lt;/span&gt; &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;   M= 속도 증가 배율&lt;/span&gt; &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;   F= 선형적인 모듈의 비율 ( 0:1)&lt;/span&gt; &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;   N= CPU갯수. &lt;/span&gt;&lt;/div&gt; &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt; &lt;/span&gt;  &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;이 수식에 따르면&lt;span style="background-color: rgb(212, 42, 27); color: rgb(255, 255, 255);"&gt; CPU의 갯수가 아무리 많아도 Parallelization이 된&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: rgb(212, 42, 27); color: rgb(255, 255, 255);"&gt; &lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;&lt;span style="background-color: rgb(212, 42, 27); color: rgb(255, 255, 255);"&gt;코드가 적으면 아무 소용이 없음&lt;/span&gt;을 보여주고 있습니다. 이점 꼭꼭 &lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;잊지 마시기 바랍니다. &lt;/span&gt;    &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;동시에 Parallelization을 한 다음에는 동작의 무결성을 검사해야 &lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;합니다. 이를 위해 Intel에서 제공하는 ThreadChecker나 ThreadProfiler를 &lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;이용할 것을 권합니다. 이것들을 쓰려면 당연히 VTune같은 Tool도 있어야 &lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;합니다. 평가판이 있으니 시도해 보시기 바랍니다. (Data race, Dead-Lock등의 &lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;문제를 잘 찾아줍니다.)&lt;/span&gt;  &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;&lt;img src="http://blogfiles10.naver.net/data18/2006/9/26/153/Amdhal_chart-jinhoy97.jpg" style="cursor: pointer;" onclick="popview(this)" width="441" height="330" /&gt;&lt;/span&gt;    &lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;2008년 현재에는 매우 많은 Software들이 병렬처리 기법을 통해 최적화 되어 나왔습니다. ComputerVisionLibrary인 OpenCV만 하더라도 이번에 나온 1.1의 경우에는 OpenMP를 지원하는 버전으로 빌드되어 나와서성능향상에 도움이 되고 있습니다.&lt;br /&gt;&lt;br /&gt;일반적으로 저는 다음 순서대로 최적화 하는 것을 권장하고 있습니다.&lt;br /&gt;&lt;br /&gt;&lt;ol style="list-style-type: decimal;"&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;먼저 Loop의 수를 줄이는 방법을 고민 합니다. &lt;/span&gt;( 100%  &amp;lt;= 성능 향상에 기여하는 정도 )&lt;br /&gt;:Loop의 수는 register를 준비하고 처리하는데&lt;span id="callbacknestworldawesometistorycom13257" style="width: 1px; height: 1px; float: right;"&gt;&lt;embed type="flash" mode="checked" sap="flash" allowscriptaccess="always" id="bootstrapperworldawesometistorycom13257" src="http://worldawesome.tistory.com/plugin/CallBack_bootstrapperSrc?nil_profile=tistory&amp;amp;nil_type=copied_post" wmode="transparent" enablecontextmenu="false" flashvars="&amp;amp;callbackId=worldawesometistorycom13257&amp;amp;host=http://worldawesome.tistory.com&amp;amp;embedCodeSrc=http%3A%2F%2Fworldawesome.tistory.com%2Fplugin%2FCallBack_bootstrapper%3F%26src%3Dhttp%3A%2F%2Fcfs.tistory.com%2Fblog%2Fplugins%2FCallBack%2Fcallback%26id%3D1%26callbackId%3Dworldawesometistorycom13257%26destDocId%3Dcallbacknestworldawesometistorycom13257%26host%3Dhttp%3A%2F%2Fworldawesome.tistory.com%26float%3Dleft" swliveconnect="true" width="1" height="1"&gt;&lt;/embed&gt;&lt;/span&gt;많은 부하가 걸립니다. 이것을 줄이는 것이 제일 첫 걸음입니다. 이중loop가 돌면 한개로 줄일 수 없는지, 두개의 loop가위/아래로 돌고 있다면 한번 돌 때 처리가 가능한지 뒤져봅니다.이차원 배열을 일차원 배열로 바꿔서 할 경우가 이런 경우일것입니다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;안해도 될 일 하고 있지 않나요?&lt;/span&gt;&lt;span style="font-size: 11pt; color: rgb(0, 0, 0);"&gt;&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;( 100% )&lt;/span&gt;&lt;br /&gt;:혹시 처리하지 않아도 되는 처리를 한다든가 대충해도 될 처리를 너무 자세하게 처리한다든지 하는 경우를 잡아 주십시오.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a title="[http://grow.egloos.com/3980399]로 이동합니다." target="_blank" href="http://grow.egloos.com/3980399"&gt;&lt;span style="font-weight: bold; color: rgb(0, 0, 0);"&gt;Code단순화를 생각해 보세요. &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;( 80% )&lt;/span&gt;&lt;br /&gt;: Greate Code &lt;/a&gt;같은 책들을 보면 C code가 Assembly로 번역되는 것을 생각해 보면서 짜라는 이야기가 나옵니다. 의외로 이것을 생각해 보면 쉽게코드가 단순해집니다. &lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Data dependency를 줄일 수 있는지 봅니다. &lt;/span&gt;( 40% )&lt;br /&gt;이런 경우 병렬 처리가 매우 힘듭니다.&lt;br /&gt;&lt;div style="border: 1px solid rgb(121, 165, 228); padding: 10px; background-color: rgb(219, 232, 251);" class="txc-textbox"&gt;for ( i = 1 ; i &amp;lt; 100; ++i)&lt;br /&gt;  a[i] = a[i-1]+ a[i+1]&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;이것은 시간상에 서로 dependency가 있기 때문입니다. 일반적으로 이런 경우가 제일 없애기 힘듭니다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;종전에 내가 작성한 코드보다 잘 작성된 코드가 있는가? &lt;/span&gt;( 10% )&lt;br /&gt;: 실제 IPP같은 라이브러리를 보면 직접 image processing코드를 작성하는 것보다 더 잘 되어 있는 경우가 많습니다. 둘중 어떤 것을 쓸지 잘 생각해 보세요.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;병렬처리에 쉽게 코드를 바꾸세요&lt;/span&gt; ( 30% )&lt;br /&gt;:1,3에 사용하는 방법을 이외에 병렬로 처리 되기 쉽게 코드를 바꿔보세요. 10000번할 일을 5000번 씩 나눠 한다든가 처리해야 할 data를 stack에 담아 두었다가 한꺼번에 처리하는 방법도 좋습니다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;그리고 Loop unrolling을 하세요.&lt;/span&gt; ( 10%)&lt;br /&gt;: loop unrolling은 속도를 빠르게 해주지는 않지만 초기 시동 속도를 빠르게 해줍니다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Tool을 바꿔보세요&lt;/span&gt; ( 20% )&lt;br /&gt;: Visual Studio 2008도 OpenMP를 처리할 때 무한 Thread생성을 하는 경우가 있더군요.Intelcompiler에서는 다행히 그런 일이 없었습니다. 그리고 Intel compiler로 compile하면 현재 출시되는CPU에따라 최적의 Instruction set ( SSE, SSE2등)을 이용할 수 있습니다. 그리고 제발...&lt;span style="background-color: rgb(87, 111, 189); color: rgb(255, 255, 255);"&gt; VTune으로 Hotspot을 먼저 찾고 분석하고 들어가세요.&lt;/span&gt; 이것 없이는 아무일도 안하는게 좋습니다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Intrinsic call을 이용하는 것을 고려해 보세요.&lt;/span&gt; ( 30% )&lt;br /&gt;: 이미 대부분의 Compiler들에서는 intrinsic call같은 것들을 이용하게 해줍니다. Intinsic call은각CPU마다 SSE같은 고급 명령 set들에 대해 직접 assembly로 짜지 않고 C함수나 C++class형식으로interface를 만들어 놓은 것입니다. (쓰기 좋습니다. )&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;성능 향상에 대한 노력은 정말 끝이 없습니다. 기법도 많고 수도 다양합니다. 하지만 가장 중요한 것, "&lt;span style="font-weight: bold; background-color: rgb(87, 111, 189); color: rgb(255, 255, 255);"&gt;쓰레기를 집어넣으면 쓰레기가 나온다"&lt;/span&gt;라는 것입니다. 느린 연산을 하고 있다면 분명 단순화 시키지 않고서는 어떤 기법도 소용없습니다. Compiler를 바꾸거나 라이브러리를 쓰는 것은 그 다음입니다.  &lt;/li&gt;&lt;/ol&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2676526535909912629-7391603804357182877?l=yhpdoit-programming.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://yhpdoit-programming.blogspot.com/feeds/7391603804357182877/comments/default' title='댓글'/><link rel='replies' type='text/html' href='http://yhpdoit-programming.blogspot.com/2009/06/processor-vs-algorithm.html#comment-form' title='0개의 덧글'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2676526535909912629/posts/default/7391603804357182877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2676526535909912629/posts/default/7391603804357182877'/><link rel='alternate' type='text/html' href='http://yhpdoit-programming.blogspot.com/2009/06/processor-vs-algorithm.html' title='[펌]Processor VS Algorithm'/><author><name>yhpdoit</name><uri>http://www.blogger.com/profile/10307760148110502844</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
