2016-08-08 6 views
1

매우 근본적이라면 죄송합니다. 이것은 내가하는 일의 단순화 된 버전입니다. 나는 커널 모듈을 작성 중이다. 실행 중일 때 두 개의 서로 다른 실제 CPU 하나가 두 개의 스레드가됩니다. 전역 변수를 사용하여 이러한 스레드 간의 특정 통신을 수행합니다. 이상한 것은 하나의 스레드에 의한 쓰기가 다른 스레드에 의한 쓰기가 때때로 보이지 않는다는 것입니다. 그 이유는 무엇일까요?하나의 CPU에 의해 쓰여진 값이 다른 것에 의해 보이지 않는 이유는 무엇입니까?

나는 그것이 메모리 장벽과 어쩌면 캐시 동기화와 관련이 있다고 생각하기 때문에 쓰기 후에 smp_wmb()를 사용해 보았지만 도움이되지는 않습니다. 그리고 내가 아는 한 캐시 동기화를 명시 적으로 제어 할 수 없습니다. 그래서 나는 좀 붙어있다.

아이디어가 있으십니까?

편집 : 설명이 단순화 된 버전임을 분명히하십시오.

+0

많은 일이있을 수 있습니다. 커널 모듈이 C로 가정하기 때문에 volatile 변수를 선언 했습니까? –

+0

@GabeSechan 예, 시도했습니다. – TFC

+0

다른 커널 코드에서 사용하는 패턴을 따르십시오. 또한 매우 특별한 일을하지 않는 한 쓰기 메모리 장벽은 쓰기 전에 있어야합니다. 이 가치는 어떤 의미를 전달합니까? –

답변

-1

저는 컴파일러 최적화로 인해 문제가 발생했다고 생각합니다.

volatile을 사용해 보셨습니까? 나는 당신의 경우에 volatile가 작동 할 것이라고 생각한다.

volatile 키워드는 동시 비 동기화 작업이 둘 이상의 소스 (프로세스)의 변수에서 수행되는 경우에 사용해야합니다. 변수가 volatile로 선언되면 마이크로 프로세서의 캐시에 변수를 복사하고 거기에서 액세스하는 것과는 달리 모든 프로세스가 항상 메모리 위치에서 직접 변수에 액세스합니다.

+0

volatile 한정자는 일반적으로 변수 값이 캐시에 있는지 메모리에 있는지에 영향을주지 않습니다. 일반적으로 변수의 값이 일시적으로 레지스터에 유지되는지 여부 만 영향을줍니다. –

0

우선, 잘못하고 있습니다. CPU 간의 적절한 동기화는 매우 복잡하고 매우 아키텍처 관련 문제입니다. 스레드 동기화를 위해 기존 커널 메커니즘 중 일부를 사용해야합니다. 특정 성능 요구 사항이 없으면 스핀 록만 사용하십시오. 그런 다음 필요한 경우 다른 동기화 메커니즘에 대해 조금 더 읽고 작업 부하에 가장 적합한 것을 찾으십시오.

직접 질문에 대답하려면 여기에 직면 할 수있는 두 가지 문제가 있습니다. 1. 일반적으로 컴파일러 장벽 (예 : barrier())이 처리하는 컴파일러 별 명령 재주문. 2. 일반적으로 메모리 장벽에 의해 처리되는 CPU 및 캐시 일관성에 의한 순서에 벗어난 실행.

세부 정보는 아키텍처 및 용도에 따라 다르지만 분석 할 수있는 코드 또는 아키텍처 세부 정보는 제공하지 않았습니다. 따라서 barrier(), smp_wmb(), smp_rmb()smp_read_barrier_depends() 중 적어도 하나와 모두를 사용해야 할 수도 있습니다.