2013-08-26 3 views
1

다중 스레드 ENV에이 개 변수를 설정내가 사용할 수있는 연동 클래스가 .. 내가 프로그래밍/C 번호에 새로 온 사람과 질문이

I 멀티 코어에있는 파일 (1 개 실/파일)에서 읽기 다중 스레드를 가지고/cpu 기계. 파일에는 틱 (입찰/정보 등) 또는 막대 (열기, 높음, 낮음, 닫기, 볼륨)가 포함될 수 있습니다. 파일을 읽는 스레드 doWork의 대상인 worker 클래스가 있습니다. 작업자/스레드는 막대 또는 틱 하나만 읽을 수 있지만 두 개 모두는 읽을 수 없습니다. 즉 한 파일은 모든 막대 또는 모든 틱 등입니다. 각 스레드는 틱 또는 막대를 자체 버퍼로 읽습니다.

성능상의 이유로 제네릭이나 상속을 사용하지 않습니다 (두 가지 모두 구현하고 성능을 테스트 할 것입니다). 나는 ringbuffer를 사용한다. (버퍼 당 1 개의 읽기/1 개의 쓰기 스레드 만 있어도 안전하다.) 또한 직원의 유형을 확인하여 진드기 또는 바가 있는지 확인합니다.

내가 원하는 것은 시간에 따라 틱이나 바를 처리하는 것입니다. 그래서 작업자가 버퍼에 막대/틱을 추가하면 시간을 가져 와서 전역 시간과 비교하기를 원합니다. 그것이 적다면 전역 실행 시간을 설정하고 전역 인덱스 변수를 설정하여 주 스레드가 데이터를 순서대로 얻기 위해 목록에서 사용할 인덱스를 알 수 있도록하십시오.

잠금을 해제해야합니까 (링 버퍼를 사용하여 잠금을 방지하지 않아도됩니까?) 또는 메인과 작업자 모두에서 연동 클래스를 어떻게 사용해야합니까?

아래의 코드는 의사 코드이므로 완전히 정확하지는 않지만 잘하면 아이디어를 얻을 수 있습니다. 나는 현명한 최선의 방법을 찾고있다.

현재 구현에서 Main에서 GetTick 또는 GetBar를 호출하기 전에 루프의 모든 simworker에서 NextTime을 호출 한 다음 주 작업자 목록에서 배열을 정렬합니다. 나는 작업자 스레드 자체에서 추적을 유지하는 것이 더 효율적일 것이며 동기화에 대해서는 확신 할 수 없을 것이라고 생각한다. 어쩌면 동기화가 필요하다면 어떤 이점도 사라지게됩니다.

의사 코드 EX : 당신은 성능에 대한 염려되는 경우

Main() 
{ 
List<worker> workers = new List<worker>; 
workers.Add(new worker(0,TICK)); 
workers.Add(new worker(1,BAR)); 
workers.Add(new worker(2,TICK)); 
workers.Add(new worker(3,BAR)); //etcc, etc.. I do this in a loop. 
//also start all workers - RunAsync.. then. 
while(isrunning) 
{ 
    if(workers[index].workerType == TICK) 
    { 
     Tick= workers[index].GetTick(); 
     //process tick.. 
    } 
    else 
    { 
     Bar b = workers[index].GetBar(); 
     //process bar.. 
    } 
} 
} 

public long mintime;  
public int index; 


class worker : BackgroundWorker 
{ 
    RingBuffer<tick> trb 
    RingBuffer<bar> brb 
int idx; 
public type workerType; 
worker(int i, type wtype) 
{ idx = i; workerType = wtype } 

doWork() 
{while(reader.NextData) ;} //calls callback.. 

callback(tick t) { trb.add(t); if(t.time < mintime) { mintime=t.time; index= idx}//??? 
callback(bar b){ brb.add(b); if(b.time < mintime) { mintime=b.time; index =idx} 
Tick GetTick() { trb.Read();} 
Bar GetBar() {brb.Read();{ 
} 
+0

나는 무식하지만 링 버퍼의 스레드 안전성을 어떻게 보장합니까? 귀하의 예제를 기반으로 각 스레드의 버퍼를 읽고 쓰고 있습니다 : 누군가 콜백 (callback)을 호출하고 메인 스레드는'GetXxxx'를 호출합니다. 메인 스레드에서 BAR/TICK가 처리되는 동안 덮어 쓰지 않도록 보장하는 것은 무엇입니까? – xxbbcc

답변

4

당신은 당신의 코드를 재 설계해야한다.

컴퓨터가 멀티 코어라는 사실은 읽기가 더 빠르다는 것을 의미하지 않습니다. 그들은 그렇지 않습니다. 실제로이 방법을 사용하면 읽기가 느려지므로 하나의 파일과 여러 스레드가 서로 다른 청크를 읽고 싶어하기 때문입니다. 디스크가 미러링 된 RAID 어레이 인 경우 더 빠른 성능을 얻을 수 있습니다. 그렇지 않으면 다중 스레드 읽기가 고유 한 파일 액세스를 위해 경쟁하기 때문에 성능이 저하됩니다.

그래서 단일 제작자 (메모리로 청크를 읽는 스레드)와 다중 소비자 (공유 메모리를 읽고 스레드를 수행하는 스레드)를보다 잘 설계하십시오.

내가 성능상의 이유로

이 그냥 바보에 대한 제네릭 또는 상속을 사용하지 않는

사이드 노트. Generics는 성능을 향상 시키도록 설계되었습니다. 이러한 코드 최적화는 사전에 피하는 것이 좋습니다. 상속은 관심을 가져야 할 규모에서 성능을 저하시키지 않습니다.

+0

나는 그가 여러 파일을 썼다 고 생각하고 각 스레드는 하나의 파일을 읽는다. – xxbbcc

+2

@xxbbcc 하드 드라이브가 여러 개있는 경우가 아니면 디스크에 헤드가 하나뿐입니다. 한 번에 하나의 파일 만 읽을 수 있습니다. 하나의 스레드가 다른 스레드가 읽히는 동안 블로킹되거나 더 나 빠지면 디스크 헤드가 끊임없이 두 파일 사이를왔다 갔다하여 성능을 극적으로 손상시킵니다. 파일이 완전히 다른 하드 드라이브에 있으면 병렬 읽기에서 실제로 얻을 수 있습니다. – Servy

+0

@Servy 알지만 병렬 읽기가 항상 느려지는 것은 반드시 사실은 아닙니다. 병렬 읽기 (단일 파일이 아닌 여러 파일에 대해)를 구현할 때마다 단일 스레드 (SSD가 아닌 HDD 사용)에서 입력 파일을 읽는 것보다 항상 빠릅니다. – xxbbcc

관련 문제