2012-04-04 3 views
3

현재 디스크에서 스트리밍되는 오디오에서 피치 감지를위한 대량 처리 알고리즘을 작성 중입니다. 직렬화 된 데이터를 거의 실시간으로 실행하도록 알고리즘을 강화했습니다..NET 용 Taskpool 시스템

이상적으로는 시스템이 실시간보다 빠르게 작동하여 실시간 데이터를 전달할 수 있고 큰 지연없이 피치 트랙 데이터를 생성 할 수 있습니다.

이제 데이터를 직렬 처리하면 속도가 훨씬 빨라질 수 있습니다. 저는 쿼드 코어 i7 (8 개의 하드웨어 스레드가 있음)에서 실행 중이므로 여러 블록에 걸쳐 처리를 확산하여 속도를 크게 향상시킬 수 있어야합니다. 내가 분석하고자하는 창 크기를 때까지 디스크 오프

  1. 스트림 데이터
  2. 버퍼 데이터 : 그것은 내가 현재 다음을 수행 지남에 따라

    .

  3. 데이터 창을 처리하십시오. n은 내가 밀어 원하는 양입니다
  4. 복사 데이터를 다시 N-샘플 ((이 되돌려 평균 80ms 창에서 1ms의 낮은 될 수 있습니다!)
  5. 린스를 반복합니다. 그것을 지금

한 번 창문이 생기면 그 데이터를 주어진 스레드 작업 버퍼에 복사 할 수 있고 결과가 기록 될 메모리 위치를 제공 할 수 있습니다. 이렇게하면 효과적으로 7까지 버퍼링 할 수 있습니다 (스레드 8에서 나가기 스레드 풀에서 처리하게 될 데이터의 양) 스레드를 처리 할 수 ​​있습니다.

오디오의 여덟 번째 창을 제출하려고하면 풀을 차단해야합니다. 스레드를 사용하여 데이터를 처리 할 수 ​​있습니다. 그 아이디어는 7 개의 스레드가 끊임없이 데이터를 처리하는 것입니다. 이전 경험에서 볼 때이 작업을 수행하면 속도가 약 5 배 향상 될 것으로 예상됩니다.

과거에는 C++에서 작성한 작업 기반의 시스템으로 작업을 완벽하게 수행 할 수 있지만이 응용 프로그램은 C#에서 개발 중입니다. C++에서 낮은 오버 헤드로 잘 병렬 처리하려면 좋은 잠금없는 큐 메커니즘을 구축하는 데 상당한 시간을 투자했습니다.

저는 C#에서 누군가 제게 이런 고통을 겪었 으면 좋겠다고 생각했습니다. 그러나 나는 일하는 것처럼 보이는 것을 찾을 수 없습니다. System.Threading.ThreadPool을 살펴 봤는데 현재 얼마나 많은 스레드가 작동 중인지 확인할 방법이 없습니다. 오버 헤드가 금지되어있는 것은 말할 것도 없습니다. 큰 문제는 작업 항목을 제출할 때마다 다시 작성하도록 미리 지정된 기존 구조 (내 처리에서 중요 함)를 다시 사용할 수 없다는 것입니다. 이것은 엄청난 단점이 있습니다. 그래서 제가 처리 할 수있는 것보다 더 빨리 작업을 생성 할 수 있습니다. 그렇게해야만 구조와 작업 공간을 설정하는 데 많은 시간을 낭비하게 될뿐만 아니라, 실제로 사용하지 말아야 할 메모리 공간이 필요하지 않게되었습니다.

그런 다음 System.Threading.Tasks에 대해 알게되었지만 그 기능도 제가 제공 한 기능을 제공하지 않는 것 같습니다.

나는 C++ 작업 관리자를 interop을 통해 사용할 수 있다고 생각하지만 실제로이 시대에 누군가 비슷한 것을 설정했다고 가정했습니다. 그래서 나는 무엇인가 놓치고 있냐? 아니면 누군가가 그러한 작업 관리 엔진에 대한 링크를 제공 할 수 있습니까?

+0

나는 잘 모르겠다. "작업 항목"을 만들 때 왜 구조를 복사해야합니까? 왜 그냥 참조를 전달하지 않는지 (즉, 클래스에 넣고 인스턴스를 전달하는 것)? – zmbq

+4

단순한 단일 제작자/다중 소비자 알고리즘보다 더 필요한 것은 없습니다. –

+0

@ zmbq : 문제는 내가 처리하기 위해 큰 스크래치 패드 영역 세트가 필요하다는 것입니다. 이러한 스크래치 패드는 반드시 설치가 쉽지 않으므로 사전 설치해야합니다. 내 C++ 시스템으로 수행 한 작업은 사전 설정 8 구조로되어 있으며 현재 처리 할 준비가 된 데이터를 다시 사용합니다. 다른 문제는 이러한 스크래치 패드가 꽤 크기 때문에 임의로 50 개를 만들 수는 없다 (50 개는 약 0.5GB의 메모리가 필요하다). – Goz

답변

4

Task Parallel Library 해결하려는 작업에 특히 적합합니다.또한이 프로세스를 파이프 라인 할 수도 있습니다.

그래서 당신은 확인해야 :

+0

나는 오히려 TPL이 내가 원하는 것을 할 수 있기를 바랬다. 그러나 지금까지는별로 운이 없었다. 예를 들어 아이템을 큐에 넣고 큐잉을 막을 때까지 어떻게해야 하는가? 스레드를 사용할 수 있습니까? – Goz

+1

@Goz - BlockingColcition 링크 아래에 있습니다. –

+0

@HenkHolterman : 예를 들어 나를 가리켜 주시겠습니까? – Goz

3

글쎄, 항상 이런 경우로 ZeroMQ을 사용하는 것이 좋습니다. 그것은 당신이 아주 쉽게 소비자의 수를 통제 할 수있게 해줄 것입니다.

스크래치 패드 영역의 경우 먼저 0.5GB는 현재의 많은 메모리가 아닙니다. 나는 내 전화기가 그 이상의 RAM을 가지고 있다고 생각한다. 내 데스크톱은 말할 것도 없다. 만약 당신이 정말로 메모리 소비에 쉽게 가길 원한다면, 스레드 당 하나의 스크래치 패드 영역을 만들고, 그것들 모두를 풀에 넣고, 프로듀서에게 스크래치 패드 영역에서 작업 대기열에 넣기 전에 해당 작업 영역을 연결하십시오. 소비자가 완료되면 스크래치 패드 영역을 풀로 되돌립니다.

+1

약 80 메가 정도만 필요로 할 때 나는 반쯤은 너에 관해서는 몰라. 기억의 끔찍한 낭비처럼 보인다 ... 아아, 나는 프로그래머가 내가하는 것처럼 생각하기를 바란다. ( – Goz

+2

기억의 낭비가 아니다. 당신의 프로그램이 끝나면 ... 진짜 문제가 아닌 이상 진지하게 메모리 풋 프린트를 최적화 할 수있는 포인트가 없습니다. 진짜 문제입니까? – zmbq

+0

예 ... 명백히 .. 자원을 불필요하게 낭비하는 것은 좋지 않지만 ... 무의미한 메모리 사용이 왜 나쁜지에 대한 논쟁에 빠지지 마십시오. – Goz

1

여기서 작업 병렬 데이터 흐름 라이브러리를 사용합니다. 병렬 처리 및 블록화 의미를 명시 적으로 제어 할 수있는 프로세스 블록을 만들 수 있도록 설계되었습니다.