프로그래밍과 잡담

Parallel for 문 사용 관련 본문

프로그래밍/C#

Parallel for 문 사용 관련

크레온 2023. 2. 14. 18:22
 

일단 C# 인거 같으니까 C#으로 범주를 셋팅함.

 

다른 언어도 비슷할거 같은데, 실험은 안 해봤으니까 일단 잊기 전에 적어 놓는다.

 

C# 에서는 Parallel 이라는 병렬 처리 기능이 있음.

 

이름부터 병렬이라는 뜻이니,  병렬연산을 할 때 사용 하라고 마소에서 만든거다..

 

근데 이거를 사용하면 30초 걸리는게 5~6초 줄어든다.

 

내꺼 cpu에서 말이지. 내 cpu는 5900x라 24쓰레드까지 지원한다.

그러니 8코어는 더 걸리겠지.

 

여하튼 이게 중요한게 아니라,  Parallel을 사용 하고 그대로 끝나는 경우도 있지만 대부분 결과 값을 어느 한곳에 집어 넣고 결과를 처리 할 것이다.

 

근데 말이야 그게 결과들을 리스트에 집어 넣는 경우에 문제가 되는거 같음.

 

멀티쓰레드에서 발생하는 문제 말이다.  데이터 경합과 같은 현상이 일어 나는거 같음. 

 

내가 겪은건, 폴더에서 파일을 읽어 들여서, 리스트에 집어 넣는건데, 그냥 for문으로 돌려버리면 겁나 느림.

그래서 Parallel로 읽어 들인건데, 문제는 List 를 검증 해보니까, null 인 항목들이 있더라구.

 

그래서 해결한 방법은 되게 간단함. 

 

그냥 해당 List 인스턴스를 lock을 걸었음. java는 synchronized 같은 예약어로 여러 쓰레드에서 동시에 접근을 못하게 하는 예약어임. 

 

// 코드는 대충 아래 처럼 썼음.

Parallel.For(0, size, (x)=>{

	// 연산 작업
    var result = job(x);
    
    //작업 후 리스트에 넣음
    // 아래의 lock 을 안 넣으면 여러쓰레드가 동시에 접근하면서 내용이 빠지는 현상이 생김.
    lock(list){
    	list.AddRange(result);
    }

})

 

 

그러니까 해결되네 ㅋ 

 

아마도 예상이지만, 많은 쓰레드가 동시에  list에 접근해서 데이터를 집어 넣으니까 중간에 빠지는 현상이 발생한거 같음.

 

멀티 쓰레드 너무 어렵네..

 

사실 이 lock 같은 방식은 사용 할 때는 최소로 해야함.

왜냐 성능이 오히려 싱글 쓰레드보다 느려질 가능성이 있음.

 

 

 
반응형
Comments