Lines Matching refs:CPU
93 - CPU 메모리 배리어.
102 (*) CPU 간 ACQUIRING 배리어의 효과.
117 (*) CPU 캐시의 영향.
123 (*) CPU 들이 저지르는 일들.
147 | CPU 1 |<----->| Memory |<----->| CPU 2 |
164 프로그램은 여러 메모리 액세스 오퍼레이션을 발생시키고, 각각의 CPU 는 그런
165 프로그램들을 실행합니다. 추상화된 CPU 모델에서 메모리 오퍼레이션들의 순서는
166 매우 완화되어 있고, CPU 는 프로그램이 인과관계를 어기지 않는 상태로 관리된다고
172 따라서 위의 다이어그램에서 한 CPU가 동작시키는 메모리 오퍼레이션이 만들어내는
173 변화는 해당 오퍼레이션이 CPU 와 시스템의 다른 부분들 사이의 인터페이스(점선)를
179 CPU 1 CPU 2
206 한발 더 나아가서, 한 CPU 가 메모리 시스템에 반영한 스토어 오퍼레이션들의 결과는
207 다른 CPU 에서의 로드 오퍼레이션을 통해 인지되는데, 이 때 스토어가 반영된 순서와
213 CPU 1 CPU 2
219 D 로 읽혀지는 값은 CPU 2 에서 P 로부터 읽혀진 주소값에 의존적이기 때문에 여기엔
227 CPU 2 는 *Q 의 로드를 요청하기 전에 P 를 Q 에 넣기 때문에 D 에 C 를 집어넣는
254 CPU 에게 기대할 수 있는 최소한의 보장사항 몇가지가 있습니다:
256 (*) 어떤 CPU 든, 의존성이 존재하는 메모리 액세스들은 해당 CPU 자신에게
261 CPU 는 다음과 같은 메모리 오퍼레이션 시퀀스를 수행 요청합니다:
266 READ_ONCE() 는 메모리 배리어 명령도 내게 되어 있어서, DEC Alpha CPU 는
274 (*) 특정 CPU 내에서 겹치는 영역의 메모리에 행해지는 로드와 스토어 들은 해당
275 CPU 안에서는 순서가 바뀌지 않은 것으로 보여집니다. 즉, 다음에 대해서:
279 CPU 는 다음의 메모리 오퍼레이션 시퀀스만을 메모리에 요청할 겁니다:
287 CPU 는 다음의 수행 요청만을 만들어 냅니다:
386 순서로 수행될 수 있으며, 이는 CPU 와 CPU 간의 상호작용이나 I/O 에 문제가 될 수
387 있습니다. 따라서 컴파일러와 CPU 가 순서를 바꾸는데 제약을 걸 수 있도록 개입할
393 시스템의 CPU 들과 여러 디바이스들은 성능을 올리기 위해 명령어 재배치, 실행
397 트릭들을 무효로 하거나 억제하는 목적으로 사용되어져서 코드가 여러 CPU 와
415 CPU 는 시간의 흐름에 따라 메모리 시스템에 일련의 스토어 오퍼레이션들을
435 (1) 에서 언급했듯이, 시스템의 CPU 들은 메모리 시스템에 일련의 스토어
436 오퍼레이션들을 던져 넣고 있으며, 거기에 관심이 있는 다른 CPU 는 그
438 다른 CPU 의 스토어 오퍼레이션의 결과에 관심을 두고 있는 CPU 가 수행 요청한
439 주소 의존성 배리어는, 배리어 앞의 어떤 로드 오퍼레이션이 다른 CPU 에서
537 메모리 배리어들은 두 CPU 간, 또는 CPU 와 디바이스 간에 상호작용의 가능성이 있을
553 완료 시점까지 _완료_ 될 것이란 보장은 없습니다; 배리어가 하는 일은 CPU 의
557 (*) 한 CPU 에서 메모리 배리어를 수행하는게 시스템의 다른 CPU 나 하드웨어에
559 만드는 간접적 영향은 두번째 CPU 가 첫번째 CPU 의 액세스들의 결과를
562 (*) 첫번째 CPU 가 두번째 CPU 의 메모리 액세스들의 결과를 바라볼 때, _설령_
563 두번째 CPU 가 메모리 배리어를 사용한다 해도, 첫번째 CPU _또한_ 그에 맞는
567 (*) CPU 바깥의 하드웨어[*] 가 메모리 액세스들의 순서를 바꾸지 않는다는 보장은
568 존재하지 않습니다. CPU 캐시 일관성 메커니즘은 메모리 배리어의 간접적
569 영향을 CPU 사이에 전파하긴 하지만, 순서대로 전파하지는 않을 수 있습니다.
595 CPU 1 CPU 2
613 하지만! CPU 2 는 B 의 업데이트를 인식하기 전에 P 의 업데이트를 인식할 수 있고,
619 그렇지 않습니다, 그리고 이 현상은 (DEC Alpha 와 같은) 여러 CPU 에서 실제로
625 CPU 1 CPU 2
643 저장되어 있을 수 있습니다. 여기서 값을 읽어오는 CPU 의 캐시의 홀수 번호 처리
649 리눅스 커널이 지원하는 CPU 들은 (1) 쓰기가 정말로 일어날지, (2) 쓰기가 어디에
655 CPU 1 CPU 2
673 사용될 수 있으며, CPU의 자연적인 순서 보장이 그런 기록들을 사라지지 않게
677 주소 의존성에 의해 제공되는 이 순서규칙은 이를 포함하고 있는 CPU 에
709 아니라 컨트롤 의존성이 존재하기 때문으로, 이런 상황에서 CPU 는 실행 속도를 더
711 CPU 는 b 로부터의 로드 오퍼레이션이 a 로부터의 로드 오퍼레이션보다 먼저 발생한
740 b = 1; /* BUG: Compiler and CPU can both reorder!!! */
772 이제 'a' 에서의 로드와 'b' 로의 스토어 사이에는 조건적 관계가 없기 때문에 CPU
822 이렇게 되면, CPU 는 변수 'a' 로부터의 로드와 변수 'b' 로의 스토어 사이의 순서를
885 완화된 순서 규칙의 CPU 는 'a' 로부터의 로드와 'c' 로의 스토어 사이에 어떤
892 컨트롤 의존성에 의해 제공되는 이 순서규칙은 이를 포함하고 있는 CPU 에
929 (*) 컨트롤 의존성은 multicopy 원자성을 제공하지 -않습니다-. 모든 CPU 들이
939 CPU 간 상호작용을 다룰 때에 일부 타입의 메모리 배리어는 항상 짝을 맞춰
951 CPU 1 CPU 2
961 CPU 1 CPU 2
971 CPU 1 CPU 2
988 CPU 1 CPU 2
1003 CPU 1
1023 | CPU 1 | : | B=2 | }
1033 | CPU 1 에 의해 메모리 시스템에 전달되는
1041 CPU 1 CPU 2
1051 여기에 별다른 개입이 없다면, CPU 1 의 쓰기 배리어에도 불구하고 CPU 2 는 CPU 1
1055 | | +------+ +-------+ | CPU 2 에 인지되는
1058 | CPU 1 | : | A=1 | \ --->| C->&Y | V
1068 | : : | CPU 2 |
1081 앞의 예에서, CPU 2 는 (B 의 값이 될) *C 의 값 읽기가 C 의 LOAD 뒤에 이어짐에도
1087 CPU 1 CPU 2
1104 | CPU 1 | : | A=1 | \ --->| C->&Y |
1114 | : : | CPU 2 |
1128 CPU 1 CPU 2
1137 CPU 1 은 쓰기 배리어를 쳤지만, 별다른 개입이 없다면 CPU 2 는 CPU 1 에서 행해진
1144 | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 |
1150 | +-------+ | CPU 2 |
1163 CPU 1 CPU 2
1173 CPU 1 에 의해 만들어진 부분적 순서가 CPU 2 에도 그대로 인지됩니다:
1179 | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 |
1185 | +-------+ | CPU 2 |
1190 모든 결과를 CPU 2 에 ---->| A->1 |------>| |
1198 CPU 1 CPU 2
1216 | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 |
1222 | +-------+ | CPU 2 |
1230 모든 결과를 CPU 2 에 ---->| A->1 |------>| 2nd |
1235 하지만 CPU 1 에서의 A 업데이트는 읽기 배리어가 완료되기 전에도 보일 수도
1242 | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 |
1248 | +-------+ | CPU 2 |
1269 많은 CPU들이 로드를 예측적으로 (speculatively) 합니다: 어떤 데이터를 메모리에서
1272 않다면, 그 데이터를 로드합니다. 이후에 실제 로드 인스트럭션이 실행되면 CPU 가
1275 해당 CPU 는 실제로는 그 값이 필요치 않았다는 사실이 나중에 드러날 수도 있는데 -
1281 CPU 1 CPU 2
1293 +-------+ | CPU 2 |
1297 CPU 는 A 의 LOAD 를 +-------+ ~ | |
1302 CPU 는 해당 LOAD 를 : : | |
1308 CPU 1 CPU 2
1323 +-------+ | CPU 2 |
1327 CPU 는 A 의 LOAD 를 +-------+ ~ | |
1339 하지만 다른 CPU 에서 업데이트나 무효화가 있었다면, 그 예측은 무효화되고 그 값은
1345 +-------+ | CPU 2 |
1349 CPU 는 A 의 LOAD 를 +-------+ ~ | |
1365 대한 상당히 직관적인 개념으로, 특정 스토어가 모든 CPU 들에게 동시에 보여지게
1366 됨을, 달리 말하자면 모든 CPU 들이 모든 스토어들이 보여지는 순서를 동의하게 되는
1369 원자성'' 라는 이름의, 특정 스토어가 모든 -다른- CPU 들에게는 동시에 보여지게
1375 CPU 1 CPU 2 CPU 3
1382 CPU 2 의 Y 로의 스토어에 사용되는 X 로드의 결과가 1 이었고 CPU 3 의 Y 로드가
1383 1을 리턴했다고 해봅시다. 이는 CPU 1 의 X 로의 스토어가 CPU 2 의 X 로부터의
1384 로드를 앞서고 CPU 2 의 Y 로의 스토어가 CPU 3 의 Y 로부터의 로드를 앞섬을
1385 의미합니다. 또한, 여기서의 메모리 배리어들은 CPU 2 가 자신의 로드를 자신의
1386 스토어 전에 수행하고, CPU 3 가 Y 로부터의 로드를 X 로부터의 로드 전에 수행함을
1387 보장합니다. 그럼 "CPU 3 의 X 로부터의 로드는 0 을 리턴할 수 있을까요?"
1389 CPU 3 의 X 로드가 CPU 2 의 로드보다 뒤에 이루어졌으므로, CPU 3 의 X 로부터의
1391 원자성으로부터 나옵니다: CPU B 에서 수행된 로드가 CPU A 의 같은 변수로부터의
1392 로드를 뒤따른다면 (그리고 CPU A 가 자신이 읽은 값으로 먼저 해당 변수에 스토어
1393 하지 않았다면) multicopy 원자성을 제공하는 시스템에서는, CPU B 의 로드가 CPU A
1398 앞의 예에서, CPU 2 의 X 로부터의 로드가 1 을 리턴했고 CPU 3 의 Y 로부터의
1399 로드가 1 을 리턴했다면, CPU 3 의 X 로부터의 로드는 1을 리턴해야만 합니다.
1402 주지는 않습니다. 예를 들어, CPU 2 의 범용 배리어가 앞의 예에서 사라져서
1405 CPU 1 CPU 2 CPU 3
1412 이 변화는 non-multicopy 원자성이 만연하게 합니다: 이 예에서, CPU 2 의 X
1413 로부터의 로드가 1을 리턴하고, CPU 3 의 Y 로부터의 로드가 1 을 리턴하는데, CPU 3
1416 핵심은, CPU 2 의 데이터 의존성이 자신의 로드와 스토어를 순서짓지만, CPU 1 의
1417 스토어에 대한 순서는 보장하지 않는다는 것입니다. 따라서, 이 예제가 CPU 1 과
1418 CPU 2 가 스토어 버퍼나 한 수준의 캐시를 공유하는, multicopy 원자성을 제공하지
1419 않는 시스템에서 수행된다면 CPU 2 는 CPU 1 의 쓰기에 이른 접근을 할 수도
1420 있습니다. 따라서, 모든 CPU 들이 여러 접근들의 조합된 순서에 대해서 동의하게
1423 범용 배리어는 non-multicopy 원자성만 보상할 수 있는게 아니라, -모든- CPU 들이
1426 제공하지 않는데, 해당 연결에 들어있는 CPU 들만이 메모리 접근의 조합된 순서에
1470 하지만, release-acquire 에 의해 제공되는 순서는 해당 연결에 동참한 CPU 들에만
1481 release-acquire 체인에 관여되지 않은 CPU 들은 그 순서에 이견을 가질 수
1511 (*) CPU 메모리 배리어.
1540 경우에는 CPU가 같은 변수로부터의 로드들을 재배치할 수도 있습니다. 이는
1547 컴파일러와 CPU가 이런 일을 못하게 하려면 다음과 같이 해야 합니다:
1552 즉, READ_ONCE() 와 WRITE_ONCE() 는 여러 CPU 에서 하나의 변수에 가해지는
1586 예를 들어, 최적화된 이 코드는 변수 a 가 다른 CPU 에 의해 "while" 문과
1612 때문입니다. 문제는 컴파일러가 'a' 의 값을 업데이트 하는건 현재의 CPU 하나
1634 알면 스토어 자체를 제거할 수 있습니다. 이번에도, 컴파일러는 현재의 CPU
1644 삭제할 겁니다. 만약 다른 CPU 가 그 사이 변수 'a' 에 다른 값을 썼다면
1713 READ_ONCE() 와 WRITE_ONCE() 가 일어난 순서도 지켜줍니다, CPU 는 당연히
1731 CPU 가 'b' 를 로드할 때, -- 'a' 가 0이 아닌데도 -- 가짜인 값, 42를 보게
1793 이 컴파일러 배리어들은 CPU 에는 직접적 효과를 전혀 만들지 않기 때문에, 결국은
1797 CPU 메모리 배리어
1800 리눅스 커널은 다음의 일곱개 기본 CPU 메모리 배리어를 가지고 있습니다:
1823 바뀌는데, 하나의 CPU 는 스스로 일관성을 유지하고, 겹치는 액세스들 역시 올바른
1835 컴파일러와 CPU 모두 재배치를 못하도록 함으로써 메모리 오퍼레이션들이 디바이스에
1879 이것들은 CPU 와 DMA 가능한 디바이스에서 모두 액세스 가능한 공유 메모리의
1884 디스크립터가 디바이스에 속해 있는지 아니면 CPU 에 속해 있는지 표시하고,
1937 리턴되는 것들), CPU 는 앞의 액세스들이 뒤따르는 것들과 병합되게끔 기다릴
2019 같은 락 변수에 대한 것이라면, 해당 락을 쥐고 있지 않은 다른 CPU 의 시야에는
2026 규정되는 크리티컬 섹션의 CPU 수행은 RELEASE 와 ACQUIRE 를 가로지를 수 있으므로,
2044 우리가 이야기 하고 있는건 재배치를 하는 CPU 에 대한 이야기이지,
2048 하지만 CPU 가 오퍼레이션들을 재배치 했다는걸 생각해 보세요. 이 예에서,
2049 어셈블리 코드 상으로는 언락이 락을 앞서게 되어 있습니다. CPU 가 이를
2052 시도합니다 (또는, 한참 후에겠지만, 잠듭니다). CPU 는 언젠가는
2068 "CPU 간 ACQUIRING 배리어 효과" 섹션도 참고하시기 바랍니다.
2127 CPU 1
2170 CPU 1 (Sleeper) CPU 2 (Waker)
2179 여기서 "task" 는 깨어나지는 쓰레드이고 CPU 1 의 "current" 와 같습니다.
2186 CPU 1 CPU 2
2265 CPU 간 ACQUIRING 배리어의 효과
2269 배리어는 동일한 락을 사용하는 다른 CPU 들의 메모리 액세스 순서에도 영향을
2276 다음의 예를 생각해 봅시다: 시스템은 두개의 스핀락 (M) 과 (Q), 그리고 세개의 CPU
2279 CPU 1 CPU 2
2288 *A 로의 액세스부터 *H 로의 액세스까지가 어떤 순서로 CPU 3 에게 보여질지에
2289 대해서는 각 CPU 에서의 락 사용에 의해 내포되어 있는 제약을 제외하고는 어떤
2290 보장도 존재하지 않습니다. 예를 들어, CPU 3 에게 다음과 같은 순서로 보여지는
2324 두개 이상의 프로세서를 가진 시스템이 있다면, 시스템의 두개 이상의 CPU 는 동시에
2328 경우, 두 CPU 모두에 영향을 끼치는 오퍼레이션들은 오동작을 막기 위해 신중하게
2374 _전에_ task 포인터가 지워진다면, 다른 CPU 는 해당 대기 프로세스를 시작해 버리고
2380 CPU 1 CPU 2
2410 이 경우에, 배리어는 시스템의 나머지 CPU 들에게 모든 배리어 앞의 메모리 액세스가
2416 컴파일러가 CPU 안에서의 순서를 바꾸거나 하지 않고 주어진 순서대로 명령을
2417 내리도록 하는 컴파일러 배리어일 뿐입니다. 오직 하나의 CPU 만 있으니, CPU 의
2435 디바이스는 CPU 에는 단지 특정 메모리 영역의 집합처럼 보이게 됩니다. 드라이버는
2440 영리한 CPU 나 컴파일러들을 사용하면 드라이버 코드의 조심스럽게 순서 맞춰진
2464 드라이버의 인터럽트 루틴이 실행 중인 동안, 해당 드라이버의 코어는 같은 CPU 에서
2498 하나의 인터럽트 루틴과 별도의 CPU 에서 수행중이며 서로 통신을 하는 두 루틴
2520 순서지어집니다. 이는 같은 CPU 쓰레드에 의한 특정 디바이스로의 MMIO
2523 2. 한 스핀락을 잡은 CPU 쓰레드에 의한 writeX() 는 같은 스핀락을 나중에
2524 잡은 다른 CPU 쓰레드에 의해 같은 주변장치를 향해 호출된 writeX()
2529 3. 특정 주변장치를 향한 특정 CPU 쓰레드의 writeX() 는 먼저 해당
2532 를 통해 할당된 전송용 DMA 버퍼로의 해당 CPU 의 쓰기가 이 CPU 가 이
2536 4. 특정 CPU 쓰레드에 의한 주변장치로의 readX() 는 같은 쓰레드에 의한
2538 dma_alloc_coherent() 를 통해 할당된 수신용 DMA 버퍼로부터의 CPU 의
2542 5. CPU 에 의한 주변장치로의 readX() 는 모든 뒤따르는 delay() 루프가
2543 수행을 시작하기 전에 완료됩니다. 이는 CPU 의 특정
2563 기능으로 매핑된 __iomem 포인터에 대해 동작할 때, 같은 CPU 쓰레드에 의한
2579 많은 CPU 아키텍쳐가 결국은 이런 주변장치를 내부의 가상 메모리 매핑을
2609 컨셉적으로 CPU 는 주어진 프로그램에 대해 프로그램 그 자체에는 인과성 (program
2611 않는다고 가정되어야만 합니다. (i386 이나 x86_64 같은) 일부 CPU 들은 코드
2616 이 말은, CPU 에게 주어지는 인스트럭션 스트림 내의 한 인스트럭션이 앞의
2626 CPU 는 최종적으로 아무 효과도 만들지 않는 인스트럭션 시퀀스는 없애버릴 수도
2637 CPU 캐시의 영향
2640 캐시된 메모리 오퍼레이션들이 시스템 전체에 어떻게 인지되는지는 CPU 와 메모리
2644 한 CPU 가 시스템의 다른 부분들과 캐시를 통해 상호작용한다면, 메모리 시스템은
2645 CPU 의 캐시들을 포함해야 하며, CPU 와 CPU 자신의 캐시 사이에서의 동작을 위한
2649 <--- CPU ---> : <----------- Memory ----------->
2653 | CPU | | Memory | : | CPU | | | | |
2663 | CPU | | Memory | : | CPU | | |--->| Device |
2671 특정 로드나 스토어는 해당 오퍼레이션을 요청한 CPU 의 캐시 내에서 동작을 완료할
2672 수도 있기 때문에 해당 CPU 의 바깥에는 보이지 않을 수 있지만, 다른 CPU 가 관심을
2673 갖는다면 캐시 일관성 메커니즘이 해당 캐시라인을 해당 CPU 에게 전달하고, 해당
2677 CPU 코어는 프로그램의 인과성이 유지된다고만 여겨진다면 인스트럭션들을 어떤
2683 메모리 배리어가 하는 일은 CPU 쪽에서 메모리 쪽으로 넘어가는 액세스들의 순서,
2687 [!] CPU 들은 항상 그들 자신의 로드와 스토어는 프로그램 순서대로 일어난 것으로
2688 보기 때문에, 주어진 CPU 내에서는 메모리 배리어를 사용할 필요가 _없습니다_.
2691 여부는 디바이스가 액세스 되는 메모리 윈도우의 특성에 의해 결정될 수도 있고, CPU
2701 읽을 수 있는데, 더티 캐시 라인이 CPU 의 캐시에 머무르고 있고, 바뀐 값이 아직
2703 적절한 부분에서 각 CPU 캐시의 문제되는 비트들을 플러시 (flush) 시켜야만 합니다
2707 CPU 의 캐시에서 RAM 으로 쓰여지는 더티 캐시 라인에 의해 덮어써질 수도 있고, CPU
2710 문제를 해결하기 위해선, 커널의 적절한 부분에서 각 CPU 의 캐시 안의 문제가 되는
2720 Memory mapped I/O 는 일반적으로 CPU 의 메모리 공간 내의 한 윈도우의 특정 부분
2733 CPU 들이 저지르는 일들
2736 프로그래머는 CPU 가 메모리 오퍼레이션들을 정확히 요청한대로 수행해 줄 것이라고
2737 생각하는데, 예를 들어 다음과 같은 코드를 CPU 에게 넘긴다면:
2745 CPU 는 다음 인스트럭션을 처리하기 전에 현재의 인스트럭션을 위한 메모리
2752 당연하지만, 실제로는 훨씬 엉망입니다. 많은 CPU 와 컴파일러에서 앞의 가정은
2765 (*) 메모리 액세스 순서는 CPU 버스와 캐시를 좀 더 잘 사용할 수 있도록 재배치
2773 (*) 해당 CPU 의 데이터 캐시가 순서에 영향을 끼칠 수도 있고, 캐시 일관성
2775 있지만 이 일관성 관리가 다른 CPU 들에도 같은 순서로 전달된다는 보장은
2778 따라서, 앞의 코드에 대해 다른 CPU 가 보는 결과는 다음과 같을 수 있습니다:
2785 하지만, CPU 는 스스로는 일관적일 것을 보장합니다: CPU _자신_ 의 액세스들은
2804 앞의 코드는 CPU 가 다음의 메모리 액세스 시퀀스를 만들도록 할겁니다:
2810 액세스들은 합쳐지거나 버려질 수 있습니다. 일부 아키텍쳐에서 CPU 는 같은 위치에
2818 컴파일러 역시 이 시퀀스의 액세스들을 CPU 가 보기도 전에 합치거나 버리거나 뒤로
2842 그리고 이 LOAD 오퍼레이션은 CPU 바깥에는 아예 보이지 않습니다.
2848 DEC Alpha CPU 는 가장 완화된 메모리 순서의 CPU 중 하나입니다. 뿐만 아니라,
2849 Alpha CPU 의 일부 버전은 분할된 데이터 캐시를 가지고 있어서, 의미적으로