Exclusive loads and store (ldrex/strex)
- ldrex/strex가 쌍이되어 특정 메모리 값을 읽고 저장하기 전에 값이 다른 요인(preemption, 다른 CPU, cache coherent port를 가진 장치 등)에 의해 바뀌었는지 알아낼 수 있다.
- preemption되는 경우 실패하게 하는 테크닉은 s/w 루틴으로 해결
- preemption되는 경우를 대비하여 context switch에서 무조건 clrex를 수행하여 강제로 실패를 만든다. 그렇게 하여 원래 수행하던 태스크로 다시 돌아왔을 때 strex가 항상 실패를 하게 할 수 있다.
- local monitor
- 각 CPU(core)에 연결되도록 설계되었다.
- non-shared 메모리에서 exclusive 명령을 사용 할 때에는 local monitor를 사용하여 exclusive/open access 상태를 확인할 수 있다.
- global monitor
- cache coherent 기능이 있는 AXI 버스와 메모리 인터페이스 중간에 연결되도록 설계되었다.
- CPU(core) 뿐만 아니라 cache coherent port가 부착된 device 장치들도 AXI 버스를 통해 메모리와 연결되어 이의 중간에 연결된 global monitor를 사용할 수 있다.
- shareable 메모리에서 exclusive 명령을 사용할 때에는 global monitor를 사용하여 exclusive/open access 상태를 확인할 수 있다.
- cache coherent 기능이 있는 AXI 버스와 메모리 인터페이스 중간에 연결되도록 설계되었다.
- local monitor와 global monitor는 단순한 state machine으로 구현되었고 ldrex/strex 사용 시 최근에 access한 CPU(core), tag 주소 및 상태(state) 들이 저장되고 이 tag 주소와 상태를 사용하여 strex의 수행 여부를 결정한다.
참고: Cache Coherent Protocol | 문c
Exclusive monitor State machine
- 메모리가 ldr/str 등으로 사용될 때에는 open access 상태에 있다.
- 메모리가 ldrex를 사용할 때에는 exclusive 상태로 마크된다.
- ldrex를 수행한 메모리 주소(캐시 라인에 포함된 주소)의 데이터가 변화되면 open access 상태로 바뀐다.
- 또 한 번 다른 CPU에 의해 strex를 수행하려고 하는 경우 exclusive 상태가 아니므로 실패한다.
- strex를 하는 경우 항상 cache line은 clean & invalidate 된다.
- 주소 지정이 항상 cache line에 관련되어 있기 때문에 원하지 않게 실패가 될 수도 있음을 고려해야 한다.
Cache bouncing (Cache line contention)
- spin lock에서 CPU가 lock을 얻기 위해 쉬지 않고 서로 ldrex/strex를 반복적으로 호출(spin)하는 경우 해당 cache line 역시 반복적으로 clean & invalidate 후 해당 CPU에서 load 되면서 성능이 급격히 떨어지게 된다. 이러한 문제를 해결하기 위해 항상 ldrex/strex의 명령을 사용하지 않고 먼저 읽어 확인 한 후 정상일 때 기록을 시도하는 방법으로 수정하여 락 메커니즘에서 cache bouncing 문제를 해결하였다.
- old ARM 아키텍처에서는 ldrex/strex 대신 swp 명령 하나로 동작하여 cache bouncing에 대해 대처하기 어려웠다.
swp(deprecated) → ldrex/strex
- swp 명령을 사용하게 되면 메모리 장치의 값을 바꾸기 위해 fetch interface 장치와 store interface 장치를 순서대로 사용하는데 이의 수행은 CPU cycle이 많이 소요된다.
- 소요되는 CPU cycle만큼 인터럽트가 pending이 되는데 이로 인해 인터럽트 latency의 증가 이슈 발생하였다.
- 이를 해결하기 위해 swp를 한 쌍의 ldrex와 strex를 추가하여 swp 명령을 대치하였다.
- swp 명령은 ARMv6 이후 부터 deprecated.
- 참고: ARM Synchronization Primitives | ARM infocenter – 다운로드 pdf