volatile unsigned int produceCount = 0, consumeCount = 0;
TokenType buffer[BUFFER_SIZE];
void producer(void) {
while (1) {
while (produceCount - consumeCount == BUFFER_SIZE)
sched_yield(); // buffer is full
buffer[produceCount % BUFFER_SIZE] = produceToken();
// a memory_barrier should go here, see the explanation above
++produceCount;
}
}
void consumer(void) {
while (1) {
while (produceCount - consumeCount == 0)
sched_yield(); // buffer is empty
consumeToken(buffer[consumeCount % BUFFER_SIZE]);
// a memory_barrier should go here, the explanation above still applies
++consumeCount;
}
}
는 메모리 장벽 버퍼에 액세스하는 라인과 Count
를 업데이트 라인 사이에 사용되어야 함을 말한다 변하기 쉬운.
이것은 CPU가 펜스 위의 지시 사항과 함께 지시 사항을 재정렬하는 것을 방지하기 위해 수행됩니다. Count
변수는 버퍼로 인덱싱되기 전에 증가되지 않아야합니다.
울타리를 사용하지 않으면 이러한 종류의 순서 재 지정이 코드의 정확성을 위반하지 않습니까? CPU는 버퍼에 인덱스하기 전에 Count
의 증가분을 수행해서는 안됩니다. 명령 reordering 동안 CPU가 데이터 의존성을 처리하지 않습니까?
감사 울타리를 사용하지 않는 경우
@ user3286661 : 이는 메모리 장벽이 잘 정의 된 C++ 위에 코드를 만들 수 없다는 것을 의미합니다. 그것은 답변에 도움이되지 않습니다, 그것은 왜 당신의 질문의 전제 결함이 설명합니다. – MSalters
@ user3286661 우리는 성능에 신경 쓰지 않습니까? 이것은 정확성에 관한 것입니다. (왜냐하면'sched_yield'에서 돌아가는 코드의 성능이 끔찍할 것이기 때문입니다.) 이것은 의사 코어이거나 플랫폼 특정 코드 여야합니다. '휘발성'이 메모리 장벽과 스레드와 상호 작용하는 방식에 대한 이식성 규칙은 없습니다. –
질문은 기억 장벽의 개념에 관한 것입니다. 우리는 성과에 신경 쓰지 않습니다. – user3286661