문제

나는 그리는 데 필요 peak 미터에서 오디오시됩니다.최소 44100 당 샘플 두 번째 시간은 최소 40 스트림이 있습니다.각 버퍼 사이 64 1024 샘플입니다.나를 잡아 아 bs max 에서 각 버퍼입니다.(이들은 다음을 통해 공급되는 종류의 로우 패스 필터링하고 그에 대해 20ms 간격으로 합니다.)

for(int i = 0; i < numSamples; i++)
{ 
      absMaxOfBuffer = MAX( fabs( buffer[i] ), absMaxOfBuffer);
}

그게 내가 그것을 지금 하십시오.하고 싶다 훨씬 빠릅니다.의 버퍼가 수레에서 -1 1 범위,따라서 팹.

질문이 있을 까다로운 comp-sci 퀵력의 방법으로 이렇게 빠르니까?

실패는,branchless ABS MAX 기능을 뜹니다,그들이 존재하는가?

편집:기본 플랫폼은 리눅스/gcc 지만 windows 포트 계획은(아마도 mingw).

편집,두 번째:
나는 수락을 onebyone 의 비트에 대한 실제 algo 구조가 중심이었다.
해 줄이기 위해 루프 네 시 비우기 signbits 고 다음을 얻으로 최대 SSE(maxps 교육)볼지 않는 경우 껍질은 바나나.주셔서 감사합니다 제안,나는 까지-투표의 몇 가지로 당신을,주자다.:)

도움이 되었습니까?

해결책

팹과 비교는 모두 IEEE 플로트에 대해 매우 빠릅니다 (원칙적으로 싱글 인트거 -OP 빠르게).

컴파일러가 두 작업을 모두 인쇄하지 않으면 작업 할 때까지 포장하거나 아키텍처의 구현을 찾아 직접 인라인으로 표시하십시오.

당신은 아마도 사실에서 무언가를 얻을 수 있습니다. 긍정적인 IEEE 플로트는 동일한 비트 패턴을 가진 정수와 같은 순서로 이동합니다. 그건,

f > g   iff   *(int*)&f > *(int*)&g

따라서 일단 당신이 Fabs를 사용하면, 나는 INT의 분기가없는 최대가 플로트에도 효과가 있다고 생각합니다 (물론 크기가 같은 것으로 가정합니다). 이것이 왜 여기에서 작동하는지에 대한 설명이 있습니다. http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm. 그러나 컴파일러는 CPU와 마찬가지로 이미이 모든 것을 알고 있으므로 차이가 없을 수도 있습니다.

복잡성이 빠른 방법은 없습니다. 알고리즘은 이미 O (N)이며이를 이길 수 없으며 모든 샘플을 볼 수 없습니다.

코드보다 클록 주기당 더 많은 데이터를 처리함으로써 프로세서의 SIMD (즉, Intel의 SSE2)에 도움이되는 것이있을 것입니다. 그러나 나는 무엇을 모른다. 있다면, 그것은 아마도 몇 배 더 빠를 것입니다.

어쨌든 40 개의 독립 스트림을 다루고 있기 때문에 멀티 코어 CPU에서 병렬화 할 수 있습니다. 그것은 몇 가지 요소가 더 빠를 것입니다. "그냥"적절한 수의 여분의 스레드를 시작하고, 그 사이에 작업을 나누고, 모두가 완료 될 때 (스레드 장벽)를 표시 할 수있는 가장 가벼운 중상 기본 사항을 사용하십시오. 40 개의 스트림의 최대를 플로팅하는지 또는 각각의 최대를 별도로 표시할지 여부는 확실하지 않으므로 결과가 다음 단계로 전달되는 것을 보장하는 것 외에는 작업자 스레드를 동기화 할 필요가 없습니다. 데이터 손상없이.

컴파일러가 루프를 얼마나 많이 풀 었는지 확인하기 위해 분해를 살펴볼 가치가 있습니다. 조금 더 끊어 버린 시도를 시도하고, 그것이 차이가 있는지 확인하십시오.

생각해야 할 또 다른 것은 얼마나 많은 캐시 수를 놓치고 있는지, 캐시에 몇 가지 단서를 제공하여 올바른 페이지를 미리로드 할 수 있도록 숫자를 줄일 수 있는지 여부입니다. 그러나 나는 이것에 대한 경험이없고, 많은 희망을지지하지 않을 것입니다. __builtin_prefetch는 GCC의 마법의 소지이며, 첫 번째 실험은 "이 블록의 루프에 들어가기 전에 다음 블록의 시작을 프리 페치"와 같은 것 같습니다.

현재 필요한 속도의 몇 퍼센트는? 아니면 "가능한 빨리"의 경우입니까?

다른 팁

그에 문서화 된 가지가없는 팹이 있습니다 http://www.scribd.com/doc/2348628/the-aggregate-magic-algorithms

또한 최근 버전의 GCC는 분기가없는 것을 인화합니다. fabs MMX 지침을 사용합니다. 도 있습니다 fmin 그리고 fmax, 그러나 GCC는 그것들을 인화하지 않을 것입니다 (당신은 얻을 수 있습니다. call fmin).

시도 할 것 :

  • fabs ()는 인라인 기능이 아닐 수 있습니다.
  • 특별 어셈블리 지침이 도움이 될 수 있습니다. 인텔에서 SSE는 한 번에 최대 4 개의 플로트를 계산하는 지침이 있습니다.
  • 실패하면 IEEE 754 사양은 A와 B가 비 음성 플로트, a <b는 *(int *) & a < *(int *) & b에 해당합니다. 또한 A의 경우 MSB를 뒤집어 A에서 A에서 A를 계산할 수 있습니다. 이러한 속성은 함께 비트 둥근 해킹을 가능하게 할 수 있습니다.
  • 모든 샘플의 최대 값이 정말로 필요합니까? 아마도 최대 값은 두 번 이상 발생할 수 있으며 모든 입력을 검사하지 않을 가능성이 높아질 수 있습니다.
  • 스트리밍 방식으로 최대 값을 계산할 수 있습니까?

당신은보고 싶을 수도 있습니다 고유.

사용하는 C ++ 템플릿 라이브러리입니다 SSE (2 이상) 및 Altivec 명령어는 벡터화되지 않은 코드로 우아한 폴백을 갖는 세트.

빠른. (벤치 마크 참조).
표현식 템플릿을 사용하면 임시를 지능적으로 제거하고 게으른 평가를 가능하게 할 수 있습니다. 이는 적절한 경우 에이 겐은 이것을 자동으로 처리하고 대부분의 경우 별명을 처리합니다.
SSE (2 이상) 및 Altivec 명령 세트에 대해 명시 적 벡터화가 수행되며, 벡터화되지 않은 코드로의 우아한 폴백이 있습니다. 표현식 템플릿을 사용하면 전체 표현식을 위해 전 세계적으로 이러한 최적화를 수행 할 수 있습니다.
고정 크기의 객체를 사용하면 동적 메모리 할당을 피하고 루프가 이해되면 풀리지 않습니다.
큰 매트릭스의 경우 캐시 친화성에 특별한주의를 기울입니다.

다른 질문으로 질문에 대답하는 것은 정확히 대답하지는 않지만, 저는 C ++ 개발자도 아닙니다.

C ++에서 이것을 개발하고 DSP를하고 있기 때문에 Matlab 또는 Octave (OpenSource)에 연결할 수없고 결과를 얻을 수 있습니까?

해당 소프트웨어에 이미 구현 된 기능 (Conv, FFT, IFFT, FIR 및 플롯 UTIL 기능과 같은 기능이 이미 있습니다. Photoshop을 살펴보고 Matlab이라는 큰 폴더가 있습니다.

도움이되기를 바랍니다.

내가 보는 쉬운 최적화 :

  • 루프를 포인터 산술 버전으로 번역하십시오 (컴파일러가 이것을 볼 수 없다고 가정).
  • IEEE 754 표준은 표현을 표지판으로 정의합니다. 따라서 가장 중요하지 않은 비트를 0으로 설정하는 것은 fabs ()를 호출하는 것과 동일합니다. 이 기능은 이미이 트릭을 사용합니다.

신의 목적을 위해 당신할 수 있 스퀘어 그 대신에 절대값;으로 수학적으로|a| < |b|경우^2 < b^2 고 그 반대입니다.곱하기보다 빠를 수 있습 팹()일부 컴퓨터에서(?), 나도 몰라.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top