2008-10-11 4 views
5

난 계산 만하는 비대화 형 CPU 기반 응용 프로그램을 개발하고 있습니다. 거의 IO가 없습니다. 현재는 너무 오래 작동하며 알고리즘을 개선하는 중에 언어 또는 플랫폼을 변경하면 어떤 이점도 줄 수 있다고 생각합니다. 현재 인텔 C++ 컴파일러로 컴파일 된 윈도우에서는 C++ (OOP가 없으므로 거의 C)입니다. ASM 도움말로 전환 할 수 있습니까? Linux 및 GCC로 전환 할 수 있습니까?CPU 바인딩 응용 프로그램에 어떤 언어/플랫폼을 권장합니까?

답변

15

그냥 철저히 조사하십시오 : 먼저 프로파일 데이터를 수집하고 두 번째로 알고리즘을 고려하십시오. 나는 당신이 그것을 알고있을 것이라고 확신하지만, 그들은 모든 성과 프로그래밍 토론에 포함되어야합니다.

"ASM 도움말로 전환 할 수 있습니까?" 그 대답은 "당신이 그 대답을 모른다면 아마 그렇지 않을 것입니다." CPU 아키텍처와 그 기능에 매우 익숙하지 않다면, 코드에서 C/C++ 컴파일러를 최적화하는 것보다 훨씬 더 나은 작업을 수행 할 것 같지 않습니다.

다음은 알고리즘 향상 이외에도 코드의 속도 향상이 선형 증가가 아닌 병렬 처리에서 발생한다는 것입니다. 데스크탑 머신은 태스크에서 4 ~ 8 개의 코어를 던질 수 있으며 약간 더 나은 코드 생성기보다 훨씬 더 뛰어난 성능을 제공합니다. C/C++에 익숙하기 때문에 OpenMP는별로 신경 쓰지 않습니다. 루프를 병렬 처리하는 것은 매우 쉽습니다 (분명히 루프에 종속 된 종속성을 관찰해야하지만 분명히 "작동 할 수있는 가장 간단한 병렬 처리"입니다).

이 모든 것을 언급 했으므로 코드 생성 품질은 C/C++ 컴파일러에 따라 다릅니다. 인텔 C++ 컴파일러는 최적화 품질에 대해 잘 알고 있으며 OpenMP 만 지원하는 것이 아니라 스레딩 구성 요소와 같은 다른 기술을 완벽하게 지원합니다.

어떤 프로그래밍 언어가 C++보다 우수할지에 대한 질문으로 이동하면 "병렬 처리 및 동시 프로그래밍의 개념을 적극적으로 촉진/촉진하는 프로그래밍 언어"가 될 것입니다. Erlang은 그 점에서 볼의 상징이며, 현재 "인기있는"언어이며, 성능 프로그래밍에 관심이있는 대부분의 사람들은 적어도 그 부분에주의를 기울이고 있습니다. 따라서 해당 영역에서 자신의 기술을 향상 시키려면 그것을 확인하고 싶다.

6

ASM으로 전환하는 것이 매우 능숙하지 않거나 더 잘 할 수 있다는 것을 알 수있는 특정 중요 경로 루틴이없는 한 많은 도움이되지 않습니다. 여러 사람들이 언급했듯이, 현대 컴파일러는 대부분의 경우 캐싱 등의 장점을 취하는 것이 더 낫습니다. 누구든지 손으로 할 수있는 것보다.

나는 좋을 것 :

  • 다른 컴파일러를 시도, 및/또는 다른 최적화 옵션
  • 실행 코드 커버리지/분석 유틸리티, 그리고 중요한 경로가 어디 파악 및 최적화에 대한 작업 코드의 코드

C++은 코드에서 가능한 최상의 성능을 제공 할 수 있어야하므로 언어를 전환하지 않는 것이 좋습니다. 응용 프로그램에 따라 다른 제안으로 다중 스레드를 사용하여 다중 코드/프로세서 시스템에서 더 나은 성능을 얻을 수 있습니다.

4

동안 그냥 인텔 C++ 컴파일러, 당신은 다음 옵션 중 하나를 시도 할 수 있습니다 당신보다 최적화의 가능성이 더 있기 때문에, 어떤 혜택을 제공하지 않습니다 ASM으로 전환 : 병렬화 컴파일러를 시도

  • 을 귀하의 코드는 VectorC 컴파일러와 같습니다.
  • MMX, 3DNow!, SSE 또는 사용자의 필요에 맞는 (또는 CPU) 무언가를 많이 사용하여 asm으로 전환하십시오. 이것은 순수한 asm보다 더 많은 이익을 줄 것입니다.
  • GPGPU를 사용해도됩니다. 즉 CPU 대신 GPU에서 알고리즘의 상당 부분을 실행합니다. 귀하의 알고리즘에 따라, 그것은 훨씬 더 빠를 수 있습니다.

편집 : 프로필 접근 방식도 두 번째입니다. Intel C++ 컴파일러를 지원하는 AQTime을 권장합니다.

3

필자는 철저히 비 병렬화 상황이 아니라면 개인적으로는 병렬 처리를 가장 쉽게 활용할 수있는 언어를 살펴볼 것입니다. 일부 여분의 코어에 볼트를 걸고 (가능한 경우!) 거의 선형적인 개선을하면 여분의 몇 퍼센트의 효율성을 압박하는 것보다 훨씬 비용 효율적일 수 있습니다.

병렬화에 관해서는 기능적 언어가 가장 좋은 방법으로 여겨지거나 OpenMP for C/C++를 볼 수 있다고 생각합니다. (개인적으로 관리되는 언어 사용자로서 Java/.NET 용 라이브러리를 살펴볼 것이지만 누구나 동일한 기본 설정을 갖고있는 것은 아닙니다.)

+0

예, 특히 Clojure를 살펴 보겠습니다. 이것은 병렬성에 대해 강박적 인 사람이 만든 JVM 언어이므로 기능적 언어 (불변의 데이터 구조와 같은)에서 많은 것을 필요로합니다. – Ken

14

항상 알고리즘은 거의 언어입니다. 여기 내 단서가 있습니다 : "알고리즘을 개선하는 중".

조정이 충분하지 않을 수 있습니다.

알고리즘의 근본적인 변화를 고려하십시오. 프로세싱을 없애고 처리 속도를 높이 지 말아야합니다. 범인은 종종 "검색"- 데이터를 통해 무언가를 찾고 반복합니다. 검색을 제거하는 방법을 찾으십시오.이것을 제거 할 수 없다면 일종의 트리 검색이나 일종의 해시지도로 선형 검색을 대체하십시오.

+0

나는 동의하지 않는다. 그것은 알고리즘과 하드웨어입니다. 알고리즘을 최소한으로 줄인 후에도, 물건 정리 방식 (예 : 캐싱 및 페이징)을하지 않으면 커다란 CPU 오버 헤드를 지불 할 수 있습니다. – Uri

+1

예. 항상 알고리즘입니다. 어떤 언어는 다른 사람들이 할 수없는 것을 표현할 수 있습니다. 어떤 사람들은 다른 언어보다 쉬운 것을 표현할 수 있습니다. 일부 작업은 C++에서 더 쉽고, 일부 작업은 더 어렵습니다. – Aaron

+1

@Aaron : 기술 수준에서 거의 모든 언어가 동일합니다. 모두 Turing Complete입니다. 그러나 어떤 것은 하나의 언어로 더 편리합니다. 알고리즘은 항상 언어와 무관합니다. –

3

try Fortran 77 - 계산에 관해서는 아무것도 프로그래밍 언어의 할아버지보다 여전히 뛰어나다. 또한 OpenMP로 여러 코어를 활용 해보십시오.

+0

믿기 어렵지만 사실입니다. (필자는 하드 코어 C++ 프로그래머입니다.) 주된 이유는 Fortran에서 엄격한 앨리어싱 규칙입니다. C/C++에서 컴파일러는 포인터가 주어진 데이터 조각을 가리키는 유일한 포인터라는 보장이 없지만, 어떤 최적화는 불가능합니다. –

0

간혹 원하는 알고리즘의 구현을 최적화 한 라이브러리를 찾을 수 있습니다. 종종 그들은 당신을 위해 멀티 스레딩을했을 것입니다.

예를 들어 LINPACK에서 LAPACK으로 전환하면 좋은 BLAS 라이브러리로 LU 분해/해결에서 10 배의 속도가 향상됩니다.

1

먼저 알고리즘을 변경할 수 있는지 알아 보려면 S.Lott이 제안했습니다.

알고리즘 선택이 맞다고 가정하면 처리중인 데이터가 많은 경우 메모리 액세스 패턴을 볼 수 있습니다. 요즘 많은 수의 크런치 어플리케이션의 경우 ALU가 아닌 메모리 버스에 묶여 있습니다. 나는 최근의 형식이었다 일부 코드 최적화 :

 
// Assume N is a big number 
for (int i=0; i<N; i++) { 
    myArray[i] = dosomething(i); 
} 
for (int i=0; i<N; i++) { 
    myArray[i] = somethingElse(myArray[i]); 
} 
... 

과 같이 그것을 변환 :이 특별한 경우

 
for (int i=0; i<N; i++) { 
    double tmp = dosomething(i); 
    tmp = somethingElse(tmp); 
    ... 
    myArray[i] = tmp; 
} 
... 

,이 2 배의 속도 향상에 대한 얻었다.

2

lobrien이 말했듯이 손으로 최적화 된 ASM 코드가 도움이되는지 알려주는 정보가 없습니다 ...그 대답은 아마도 "아직 아니다"라는 뜻입니다.

프로필러로 코드를 실행 해 보셨습니까?

메모리 제약 조건 또는 프로세서 제약으로 인해 코드가 느린 지 알고 계십니까?

사용 가능한 모든 코어를 사용하고 있습니까?

O (1)이 아닌 알고리즘을 사용하고 있습니까? O (1)에 그들을 데려 올 수 있습니까? 그렇지 않다면 왜 안 되겠습니까?

이 모든 작업을 수행했다면 프로그램을 실행하는 환경에 대해 어느 정도로 제어 할 수 있습니까? (아마도 당신이 운영 체제를 바꾸려고 생각한다면 많은 것들이있을 것입니다.) 다른 프로세스를 비활성화 할 수 있고, 프로세스에 우선 순위를 부여 할 수 있습니까? 더 빠른 프로세서, 더 많은 코어 또는 더 많은 메모리가있는 머신을 찾는 것 (제약 조건에 따라 다름)

계속 켜고 있습니다.

이미 모든 작업을 완료했다면 "이 몇 줄의 코드를 여기보다 더 최적화 할 수 있을지 궁금해 할 것입니다. 지금 디버거를보고있는 중입니까? " 그 시점에서 구체적으로 질문 할 수 있습니다.

행운을 빈다. 해결할 재미있는 문제를 해결하고 있습니다.

0

인텔 컴파일러에서 C++을 고수하고 있다면 compiler intrinsics (전체 참조 here)을 살펴보십시오. VC++에 similar functionality이 있다는 것을 알고 있습니다. gcc로 똑같은 일을 할 수있을 것입니다. 이를 통해 CPU에 내장 된 병렬 처리를 최대한 활용할 수 있습니다. 성능을 어느 정도 향상 시키려면 MMX, SSE 및 SSE2 명령어를 사용할 수 있습니다. 다른 사람들이 말했듯이, 아마도 알고리즘을 처음 보는 것이 가장 좋습니다.

0

알고리즘을 다시 생각해 보시거나 더 나은 방법을 생각해보십시오. 반면에 계산하려고하는 것은 계산 시간이 많이 걸릴 수도 있습니다. 어떤 종류의 클러스터에서 실행할 수 있도록 분산되어 있다고 생각하십니까? inner loops을위한 어셈블러를 도입하여 순수 코드 최적화에 집중하고자한다면 자주 (당신이하는 일을 안다면) 매우 유익 할 것입니다.

3

C++이 당신을 위해 할 수있는 것에 비해 ASM 코드를 최적화하는 것이 거의 비용 효율적이지 않습니다.

전통적인 알고리즘보기에서 알고리즘을 수행 할 수있는 모든 작업을 수행했으며 초과 작업도 제거한 경우 SOL이거나 일 수 있습니다. 하드웨어 관점에서 프로그램을 최적화 할 수 있습니다 .

예를 들어, 힙 주변의 포인터를 따라갈 때마다 분기 예측에 영향을주는 캐시 누락, 페이징 등으로 인해 막대한 비용을 지불하게됩니다. 대부분의 프로그래머 (C 전문가조차도)는 뒤에서 일어나는 일보다는 기능적 관점에서 CPU를 보는 경향이 있습니다. 때로는 "평평하게"하거나 같은 페이지에 맞도록 수동으로 메모리를 할당하여 메모리를 재구성하면 엄청난 속도 향상을 얻을 수 있습니다. 나는 구조를 평평하게함으로써 그래프 횡단에 2 배의 속도 향상을 얻을 수있었습니다.

이것은 프로그램에 대한 높은 수준의 이해를 기반으로하기 때문에 컴파일러가 수행 할 작업이 아닙니다.

0

최신 프로세서의 경우 ASM을 배우면 오랜 시간이 걸립니다. 또한 SSE의 모든 다른 버전으로 코드가 매우 프로세서 의존적이게됩니다.

꽤 많은 CPU 작업을 수행하며 인텔의 C++ 컴파일러와 g ++의 차이가 대개 (최대 15 % 정도) 크지 않으며 Mac과 측정 가능한 차이가 없음을 발견했습니다 OS X, Windows 및 Linux.

코드를 최적화하고 알고리즘을 직접 개선해야합니다. 훨씬 더 빨리 두려워하는 기존의 코드를 만들 수있는 "마술 요정 먼지"는 없습니다.

아직 성능에 관심이 없다면 좋은 프로파일 러를 통해 코드를 실행해야합니다 (개인적으로 kcachegrind & valgrind 또는 Mac OS X의 Shark를 좋아합니다. 두려워하는 창문에 좋다).

과거의 경험에 비추어 볼 때, CPU 시간의 95 %를 사용하는 방법이있을 수 있으며 캐싱을 간단히 변경하거나 추가하면 성능이 크게 향상됩니다. 비슷한 메모에서 어떤 방법이 CPU 시간의 1 % 만 사용하는 경우 최적화가 필요 없으므로 아무 것도 얻을 수 없습니다.

0

"CPU 바인딩"에 대한 2 가지 명백한 대답은 다음과 같습니다. 1. 더 많은 CPU (코어) 사용 2. 다른 것을 사용하십시오.

1 대신 2 개의 스레드를 사용하면 소요 시간이 최대 50 % 단축됩니다. 비교에서 C++에서 ASM으로는 거의 5 %를 제공하지 못합니다 (초보자 ASM 프로그래머에게는 흔히 -5 %입니다!). 일부 문제는 확장 성이 좋으며 8 개 또는 16 개 코어의 이점을 얻을 수 있습니다. 그런 종류의 하드웨어는 여전히 주류이기 때문에 문제가 해당 카테고리에 속하는지 확인하십시오.

다른 해결책은 작업에보다 특수화 된 하드웨어를 던지기위한 것입니다. 이것은 CPU의 벡터 단위 일 수 있습니다 - Windows = x86/x64를 고려하면 SSE의 특징이 될 것입니다. 벡터 하드웨어의 또 다른 종류는 최신 GPU입니다. GPU에는 자체 메모리 버스가있어 매우 빠릅니다.

0

First get the lead out. 그러면 최대한 빨리 ASM에 가지 않고도 될 수 있습니다. 하지만 ASM으로 가야한다고 생각하는 이유는 무엇이 느린지 알고 있다고 가정하고, 당신이 추측하고있는 도넛을 걸 겠어.

0

개선 된 부분이없는 코드를 최적화했다면 CPU를 늘리십시오. 이것은 다른 플랫폼에서 수행 할 수 있습니다. 내가 개발 한 것은 Appistry입니다. 몇 링크 :

http://www.appistry.com/resource-library/index.html

당신은 여기에서 무료로 제품을 다운로드 할 수 있습니다

http://www.appistry.com/developers/

내가 Appistry 작동

우리가 CPU의 확산에 구속되었다 작업에 많은 설치를 완료 한 10 대 또는 100 대가 넘는 기계에서 운동하십시오. 이 도움이

희망, -Brett

1

Oregonghost 이미 암시로 - VectorC 컴파일러는 도움이 될 수 있습니다. 실제로 코드를 병렬 처리하지는 않지만 대신 mmx 또는 sse와 같은 확장 명령 세트를 활용하는 데 사용할 수 있습니다. 소프트웨어 렌더링 엔진에서 가장 중요한 부분에 사용했기 때문에 대부분의 프로세서에서 약 150 % -200 %의 속도 향상을 가져 왔습니다.

0

Linux

Linux로 전환하면 실제로 필요한 부분 만 제거 할 수 있습니다.

-1

순진한 C 또는 C++ 코드보다 빠른 ASM 코드를 생성하기가 어렵습니다. 대부분의 경우이 작업을 잘 수행하면 몇 퍼센트가 넘지 않으며 10 %의 속도 향상은 큰 성공으로 간주되지만 대부분의 경우에는 불가능합니다.

컴파일러는 효율적으로 컴파일하는 방법을 이해할 수 있습니다. 최적화 할 위치를 파악하려면 프로필을 작성해야합니다.

0

CrowdProcess에는 알고리즘을 계산하는 데 사용할 수있는 약 2,000 명의 직원이 있습니다. API는 매우 간단하며 우리는 작업자 수에 근접한 속도 향상을 관찰 해 왔습니다. 또한 C++이나 ASM보다 생산성을 높여야하는 Javascript를 작성할 수 있습니다.

C++ 또는 ASM 사이에 있다면 모든 CPU 코어를 먼저 사용해야하며 충분하지 않으면 CrowdProcess가 흥미로운 플랫폼이어야합니다.

면책 조항 : CrowdProcess를 작성했습니다.

관련 문제