펜티엄 4 초기모델 (HT 비지원)도 스레드 수준 병렬 실행이 가능한가요?
글쓴이: 체스맨 / 작성시간: 화, 2006/05/16 - 6:39오후
간단히 변수 증감 테스트를 했습니다. 다음과 유사한 코드를 여러 스레드에서 실행합니다.
void func( void* param ) { while( !term ) { val ++; f(); /* 임의 함수 */ val --; } }
모든 스레드를 정상 종료시켰을 때 val 값이 0 이 나오지 않는 경우가 있는 프로세서는 스레드 수준 병렬 실행이 되는 것으로 예상됩니다.
제가 가지고 있는 P3 600 은 결과가 항상 0 이 나오지만, P4 2GHz (HT 비지원) 모델은 0이 아닌 값도 나옵니다.
P4 초기 모델에 대한 정확한 스펙을 찾을 수 없었습니다. P4 초기 모델도 일부 코드가 스레드 수준에서 병렬 실행 가능한 스펙을 가지고 있는 것인가요?
Forums:
일반적인(?) OS에서는
일반적인(?) OS에서는 f()진입과 val++ 이전단계에서 task switching이 발생하면 0이 아닌 경우가 나옵니다. HT랑은 별상관 없어보이네요.
Task switching 이
Task switching 이 일어나도 문제가 없습니다. Task switching 되었다해도, 스레드가 정상 종료되면 어쨌든 증가한만큼 감소가 일어날테니까요. 위에서 말씀 드린 결과 값은 생성한 스레드가 모두 종료된 시점에서의 값입니다.
volatile 선언했지만, 혹여라도 val 이 최적화 되는 경우를 피하기 위해 f 를 호출했을 뿐입니다.
스레드 수준 병렬 실행이 일어나는 경우가 아니라면 결과가 0 이 아닌 값이 나올 수 없다고 생각합니다.
말씀 드렸듯이 P3 600 에서는 결과가, 아직까지 테스트한 경우에서는 모두 0이었습니다. 하지만, P4 2Ghz 에서는 빈번히 0 이 아닌 경우가 나옵니다. 그리고 HT 지원되는 P4 에서는 당연하겠지만 매우 황당하게 크거나 작은 값이 나옵니다. 물론 이때 spin lock 을 걸어주면 결과는 모든 경우 항상 0 입니다.
Orion Project : http://orionids.org
문제가 없을 리 없지요.
물론 f()에서가 아니라 val++ 혹은 val-- 실행 도중에 switching이 일어나는 경우에 문제가 생깁니다. 구체적으로 말하면 (예컨대 val++의 경우)
1) val 값을 읽는다
2) 읽어들인 val 값에 1을 더한다
3) 2)에서 계산한 값을 다시 val에 저장한다
4) 1)에서 읽어들인 값을 반환한다
에서 1)과 3) 사이의 어느 시점에 switching이 일어나면 val값에 문제가 생길 수 있습니다. val++ 자체는 C/C++ 에서는 하나의 항목이지만 하나의 기계어 명령어는 아니므로 그 중간에서 switching이 발생할 수 있는 것이 당연합니다.
해당 부분은 매우 짧은 코드이므로 이런 일이 발생할 가능성은 상대적으로 낮지만, 이러한 형태는 race condition의 가장 단순한 예로서 교과서 등에 종종 등장하는 것이기도 합니다. HT가 지원되는가 지원되지 않는가 여부에 관계없이, switching은 어디에서든 일어날 수 있습니다.
아.. 그렇군요. 미처
아.. 그렇군요. 미처 그렇게 생각하지 못하고,
inc/dec 를 하나의 인스트럭션으로 간주하고 있었습니다.
PIII 600 에서는 스케쥴링상 그런 경우가 발생하지 않았던 것 같습니다.
잠재적 문제는 거기서도 여전이 있을 것 같군요.
Orion Project : http://orionids.org
댓글 달기