Merge tag 'docs-4.15-2' of git://git.lwn.net/linux
[muen/linux.git] / Documentation / translations / ko_KR / memory-barriers.txt
index ec3b46e27b7aa3aeca361d169bfda8ea09bf91fb..0a0930ab415668a97ef649931f4af58c6fb2e2c1 100644 (file)
@@ -82,7 +82,7 @@ Documentation/memory-barriers.txt
      - SMP 배리어 짝맞추기.
      - 메모리 배리어 시퀀스의 예.
      - 읽기 메모리 배리어 vs 로드 예측.
-     - 이행성
+     - Multicopy 원자성.
 
  (*) 명시적 커널 배리어.
 
@@ -656,6 +656,11 @@ Documentation/RCU/rcu_dereference.txt 파일을 주의 깊게 읽어 주시기 
 해줍니다.
 
 
+데이터 의존성에 의해 제공되는 이 순서규칙은 이를 포함하고 있는 CPU 에
+지역적임을 알아두시기 바랍니다.  더 많은 정보를 위해선 "Multicopy 원자성"
+섹션을 참고하세요.
+
+
 데이터 의존성 배리어는 매우 중요한데, 예를 들어 RCU 시스템에서 그렇습니다.
 include/linux/rcupdate.h 의 rcu_assign_pointer() 와 rcu_dereference() 를
 참고하세요.  여기서 데이터 의존성 배리어는 RCU 로 관리되는 포인터의 타겟을 현재
@@ -864,38 +869,10 @@ CPU 는 b 로부터의 로드 오퍼레이션이 a 로부터의 로드 오퍼레
 주어진 if 문의 then 절과 else 절에게만 (그리고 이 두 절 내에서 호출되는
 함수들에게까지) 적용되지, 이 if 문을 뒤따르는 코드에는 적용되지 않습니다.
 
-마지막으로, 컨트롤 의존성은 이행성 (transitivity) 을 제공하지 -않습니다-.  이건
-'x' 와 'y' 가 둘 다 0 이라는 초기값을 가졌다는 가정 하의 두개의 예제로
-보이겠습니다:
-
-       CPU 0                     CPU 1
-       =======================   =======================
-       r1 = READ_ONCE(x);        r2 = READ_ONCE(y);
-       if (r1 > 0)               if (r2 > 0)
-         WRITE_ONCE(y, 1);         WRITE_ONCE(x, 1);
-
-       assert(!(r1 == 1 && r2 == 1));
-
-이 두 CPU 예제에서 assert() 의 조건은 항상 참일 것입니다.  그리고, 만약 컨트롤
-의존성이 이행성을 (실제로는 그러지 않지만) 보장한다면, 다음의 CPU 가 추가되어도
-아래의 assert() 조건은 참이 될것입니다:
 
-       CPU 2
-       =====================
-       WRITE_ONCE(x, 2);
+컨트롤 의존성에 의해 제공되는 이 순서규칙은 이를 포함하고 있는 CPU 에
+지역적입니다.  더 많은 정보를 위해선 "Multicopy 원자성" 섹션을 참고하세요.
 
-       assert(!(r1 == 2 && r2 == 1 && x == 2)); /* FAILS!!! */
-
-하지만 컨트롤 의존성은 이행성을 제공하지 -않기- 때문에, 세개의 CPU 예제가 실행
-완료된 후에 위의 assert() 의 조건은 거짓으로 평가될 수 있습니다.  세개의 CPU
-예제가 순서를 지키길 원한다면, CPU 0 와 CPU 1 코드의 로드와 스토어 사이, "if"
-문 바로 다음에 smp_mb()를 넣어야 합니다.  더 나아가서, 최초의 두 CPU 예제는
-매우 위험하므로 사용되지 않아야 합니다.
-
-이 두개의 예제는 다음 논문:
-http://www.cl.cam.ac.uk/users/pes20/ppc-supplemental/test6.pdf 와
-이 사이트: https://www.cl.cam.ac.uk/~pes20/ppcmem/index.html 에 나온 LB 와 WWC
-리트머스 테스트입니다.
 
 요약하자면:
 
@@ -930,8 +907,8 @@ http://www.cl.cam.ac.uk/users/pes20/ppc-supplemental/test6.pdf 와
 
   (*) 컨트롤 의존성은 보통 다른 타입의 배리어들과 짝을 맞춰 사용됩니다.
 
-  (*) 컨트롤 의존성은 이행성을 제공하지 -않습니다-.  이행성이 필요하다면,
-      smp_mb() 를 사용하세요.
+  (*) 컨트롤 의존성은 multicopy 원자성을 제공하지 -않습니다-.  모든 CPU 들이
+      특정 스토어를 동시에 보길 원한다면, smp_mb() 를 사용하세요.
 
   (*) 컴파일러는 컨트롤 의존성을 이해하고 있지 않습니다.  따라서 컴파일러가
       여러분의 코드를 망가뜨리지 않도록 하는건 여러분이 해야 하는 일입니다.
@@ -943,13 +920,14 @@ SMP 배리어 짝맞추기
 CPU 간 상호작용을 다룰 때에 일부 타입의 메모리 배리어는 항상 짝을 맞춰
 사용되어야 합니다.  적절하게 짝을 맞추지 않은 코드는 사실상 에러에 가깝습니다.
 
-범용 배리어들은 범용 배리어끼리도 짝을 맞추지만 이행성이 없는 대부분의 다른
-타입의 배리어들과도 짝을 맞춥니다.  ACQUIRE 배리어는 RELEASE 배리어와 짝을
-맞춥니다만, 둘 다 범용 배리어를 포함해 다른 배리어들과도 짝을 맞출 수 있습니다.
-쓰기 배리어는 데이터 의존성 배리어나 컨트롤 의존성, ACQUIRE 배리어, RELEASE
-배리어, 읽기 배리어, 또는 범용 배리어와 짝을 맞춥니다.  비슷하게 읽기 배리어나
-컨트롤 의존성, 또는 데이터 의존성 배리어는 쓰기 배리어나 ACQUIRE 배리어,
-RELEASE 배리어, 또는 범용 배리어와 짝을 맞추는데, 다음과 같습니다:
+범용 배리어들은 범용 배리어끼리도 짝을 맞추지만 multicopy 원자성이 없는
+대부분의 다른 타입의 배리어들과도 짝을 맞춥니다.  ACQUIRE 배리어는 RELEASE
+배리어와 짝을 맞춥니다만, 둘 다 범용 배리어를 포함해 다른 배리어들과도 짝을
+맞출 수 있습니다.  쓰기 배리어는 데이터 의존성 배리어나 컨트롤 의존성, ACQUIRE
+배리어, RELEASE 배리어, 읽기 배리어, 또는 범용 배리어와 짝을 맞춥니다.
+비슷하게 읽기 배리어나 컨트롤 의존성, 또는 데이터 의존성 배리어는 쓰기 배리어나
+ACQUIRE 배리어, RELEASE 배리어, 또는 범용 배리어와 짝을 맞추는데, 다음과
+같습니다:
 
        CPU 1                 CPU 2
        ===============       ===============
@@ -975,7 +953,7 @@ RELEASE 배리어, 또는 범용 배리어와 짝을 맞추는데, 다음과 같
        ===============       ===============================
        r1 = READ_ONCE(y);
        <범용 배리어>
-       WRITE_ONCE(y, 1);     if (r2 = READ_ONCE(x)) {
+       WRITE_ONCE(x, 1);     if (r2 = READ_ONCE(x)) {
                                 <묵시적 컨트롤 의존성>
                                 WRITE_ONCE(y, 1);
                              }
@@ -1361,57 +1339,74 @@ A 의 로드 두개가 모두 B 의 로드 뒤에 있지만, 서로 다른 값
                                                :       :       +-------+
 
 
-이행
-------
+MULTICOPY 원자
+----------------
 
-이행성(transitivity)은 실제의 컴퓨터 시스템에서 항상 제공되지는 않는, 순서
-맞추기에 대한 상당히 직관적인 개념입니다.  다음의 예가 이행성을 보여줍니다:
+Multicopy 원자성은 실제의 컴퓨터 시스템에서 항상 제공되지는 않는, 순서 맞추기에
+대한 상당히 직관적인 개념으로, 특정 스토어가 모든 CPU 들에게 동시에 보여지게
+됨을, 달리 말하자면 모든 CPU 들이 모든 스토어들이 보여지는 순서를 동의하게 되는
+것입니다.  하지만, 완전한 multicopy 원자성의 사용은 가치있는 하드웨어
+최적화들을 무능하게 만들어버릴 수 있어서, 보다 완화된 형태의 ``다른 multicopy
+원자성'' 라는 이름의, 특정 스토어가 모든 -다른- CPU 들에게는 동시에 보여지게
+하는 보장을 대신 제공합니다.  이 문서의 뒷부분들은 이 완화된 형태에 대해 논하게
+됩니다만, 단순히 ``multicopy 원자성'' 이라고 부르겠습니다.
+
+다음의 예가 multicopy 원자성을 보입니다:
 
        CPU 1                   CPU 2                   CPU 3
        ======================= ======================= =======================
                { X = 0, Y = 0 }
-       STORE X=1               LOAD X                  STORE Y=1
-                               <범용 배리어>              <범용 배리어>
-                               LOAD Y                  LOAD X
-
-CPU 2 의 X 로드가 1을 리턴했고 Y 로드가 0을 리턴했다고 해봅시다.  이는 CPU 2 의
-X 로드가 CPU 1 의 X 스토어 뒤에 이루어졌고 CPU 2 의 Y 로드는 CPU 3 의 Y 스토어
-전에 이루어졌음을 의미합니다.  그럼 "CPU 3 의 X 로드는 0을 리턴할 수 있나요?"
-
-CPU 2 의 X 로드는 CPU 1 의 스토어 후에 이루어졌으니, CPU 3 의 X 로드는 1을
-리턴하는게 자연스럽습니다.  이런 생각이 이행성의 한 예입니다: CPU A 에서 실행된
-로드가 CPU B 에서의 같은 변수에 대한 로드를 뒤따른다면, CPU A 의 로드는 CPU B
-의 로드가 내놓은 값과 같거나 그 후의 값을 내놓아야 합니다.
-
-리눅스 커널에서 범용 배리어의 사용은 이행성을 보장합니다.  따라서, 앞의 예에서
-CPU 2 의 X 로드가 1을, Y 로드는 0을 리턴했다면, CPU 3 의 X 로드는 반드시 1을
-리턴합니다.
-
-하지만, 읽기나 쓰기 배리어에 대해서는 이행성이 보장되지 -않습니다-.  예를 들어,
-앞의 예에서 CPU 2 의 범용 배리어가 아래처럼 읽기 배리어로 바뀐 경우를 생각해
-봅시다:
+       STORE X=1               r1=LOAD X (reads 1)     LOAD Y (reads 1)
+                               <범용 배리어>              <읽기 배리어>
+                               STORE Y=r1              LOAD X
+
+CPU 2 의 Y 로의 스토어에 사용되는 X 로드의 결과가 1 이었고 CPU 3 의 Y 로드가
+1을 리턴했다고 해봅시다.  이는 CPU 1 의 X 로의 스토어가 CPU 2 의 X 로부터의
+로드를 앞서고 CPU 2 의 Y 로의 스토어가 CPU 3 의 Y 로부터의 로드를 앞섬을
+의미합니다.  또한, 여기서의 메모리 배리어들은 CPU 2 가 자신의 로드를 자신의
+스토어 전에 수행하고, CPU 3 가 Y 로부터의 로드를 X 로부터의 로드 전에 수행함을
+보장합니다.  그럼 "CPU 3 의 X 로부터의 로드는 0 을 리턴할 수 있을까요?"
+
+CPU 3 의 X 로드가 CPU 2 의 로드보다 뒤에 이루어졌으므로, CPU 3 의 X 로부터의
+로드는 1 을 리턴한다고 예상하는게 당연합니다.  이런 예상은 multicopy
+원자성으로부터 나옵니다: CPU B 에서 수행된 로드가 CPU A 의 같은 변수로부터의
+로드를 뒤따른다면 (그리고 CPU A 가 자신이 읽은 값으로 먼저 해당 변수에 스토어
+하지 않았다면) multicopy 원자성을 제공하는 시스템에서는, CPU B 의 로드가 CPU A
+의 로드와 같은 값 또는 그 나중 값을 리턴해야만 합니다.  하지만, 리눅스 커널은
+시스템들이 multicopy 원자성을 제공할 것을 요구하지 않습니다.
+
+앞의 범용 메모리 배리어의 사용은 모든 multicopy 원자성의 부족을 보상해줍니다.
+앞의 예에서, CPU 2 의 X 로부터의 로드가 1 을 리턴했고 CPU 3 의 Y 로부터의
+로드가 1 을 리턴했다면, CPU 3 의 X 로부터의 로드는 1을 리턴해야만 합니다.
+
+하지만, 의존성, 읽기 배리어, 쓰기 배리어는 항상 non-multicopy 원자성을 보상해
+주지는 않습니다.  예를 들어, CPU 2 의 범용 배리어가 앞의 예에서 사라져서
+아래처럼 데이터 의존성만 남게 되었다고 해봅시다:
 
        CPU 1                   CPU 2                   CPU 3
        ======================= ======================= =======================
                { X = 0, Y = 0 }
-       STORE X=1               LOAD X                  STORE Y=1
-                               <읽기 배리어>              <범용 배리어>
-                               LOAD Y                  LOAD X
-
-이 코드는 이행성을 갖지 않습니다: 이 예에서는, CPU 2 의 X 로드가 1을
-리턴하고, Y 로드는 0을 리턴하지만 CPU 3 의 X 로드가 0을 리턴하는 것도 완전히
-합법적입니다.
-
-CPU 2 의 읽기 배리어가 자신의 읽기는 순서를 맞춰줘도, CPU 1 의 스토어와의
-순서를 맞춰준다고는 보장할 수 없다는게 핵심입니다.  따라서, CPU 1 과 CPU 2 가
-버퍼나 캐시를 공유하는 시스템에서 이 예제 코드가 실행된다면, CPU 2 는 CPU 1 이
-쓴 값에 좀 빨리 접근할 수 있을 것입니다.  따라서 CPU 1 과 CPU 2 의 접근으로
-조합된 순서를 모든 CPU 가 동의할 수 있도록 하기 위해 범용 배리어가 필요합니다.
-
-범용 배리어는 "글로벌 이행성"을 제공해서, 모든 CPU 들이 오퍼레이션들의 순서에
-동의하게 할 것입니다.  반면, release-acquire 조합은 "로컬 이행성" 만을
-제공해서, 해당 조합이 사용된 CPU 들만이 해당 액세스들의 조합된 순서에 동의함이
-보장됩니다.  예를 들어, 존경스런 Herman Hollerith 의 C 코드로 보면:
+       STORE X=1               r1=LOAD X (reads 1)     LOAD Y (reads 1)
+                               <데이터 의존성>           <읽기 배리어>
+                               STORE Y=r1              LOAD X (reads 0)
+
+이 변화는 non-multicopy 원자성이 만연하게 합니다: 이 예에서, CPU 2 의 X
+로부터의 로드가 1을 리턴하고, CPU 3 의 Y 로부터의 로드가 1 을 리턴하는데, CPU 3
+의 X 로부터의 로드가 0 을 리턴하는게 완전히 합법적입니다.
+
+핵심은, CPU 2 의 데이터 의존성이 자신의 로드와 스토어를 순서짓지만, CPU 1 의
+스토어에 대한 순서는 보장하지 않는다는 것입니다.  따라서, 이 예제가 CPU 1 과
+CPU 2 가 스토어 버퍼나 한 수준의 캐시를 공유하는, multicopy 원자성을 제공하지
+않는 시스템에서 수행된다면 CPU 2 는 CPU 1 의 쓰기에 이른 접근을 할 수도
+있습니다.  따라서, 모든 CPU 들이 여러 접근들의 조합된 순서에 대해서 동의하게
+하기 위해서는 범용 배리어가 필요합니다.
+
+범용 배리어는 non-multicopy 원자성만 보상할 수 있는게 아니라, -모든- CPU 들이
+-모든- 오퍼레이션들의 순서를 동일하게 인식하게 하는 추가적인 순서 보장을
+만들어냅니다.  반대로, release-acquire 짝의 연결은 이런 추가적인 순서는
+제공하지 않는데, 해당 연결에 들어있는 CPU 들만이 메모리 접근의 조합된 순서에
+대해 동의할 것으로 보장됨을 의미합니다.  예를 들어, 존경스런 Herman Hollerith
+의 코드를 C 코드로 변환하면:
 
        int u, v, x, y, z;
 
@@ -1444,8 +1439,7 @@ CPU 2 의 읽기 배리어가 자신의 읽기는 순서를 맞춰줘도, CPU 1
        }
 
 cpu0(), cpu1(), 그리고 cpu2() 는 smp_store_release()/smp_load_acquire() 쌍의
-연결을 통한 로컬 이행성에 동참하고 있으므로, 다음과 같은 결과는 나오지 않을
-겁니다:
+연결에 참여되어 있으므로, 다음과 같은 결과는 나오지 않을 겁니다:
 
        r0 == 1 && r1 == 1 && r2 == 1
 
@@ -1454,8 +1448,9 @@ cpu0() 의 쓰기를 봐야만 하므로, 다음과 같은 결과도 없을 겁
 
        r1 == 1 && r5 == 0
 
-하지만, release-acquire 타동성은 동참한 CPU 들에만 적용되므로 cpu3() 에는
-적용되지 않습니다.  따라서, 다음과 같은 결과가 가능합니다:
+하지만, release-acquire 에 의해 제공되는 순서는 해당 연결에 동참한 CPU 들에만
+적용되므로 cpu3() 에, 적어도 스토어들 외에는 적용되지 않습니다.  따라서, 다음과
+같은 결과가 가능합니다:
 
        r0 == 0 && r1 == 1 && r2 == 1 && r3 == 0 && r4 == 0
 
@@ -1482,8 +1477,8 @@ u 로의 스토어를 cpu1() 의 v 로부터의 로드 뒤에 일어난 것으
 이런 결과는 어떤 것도 재배치 되지 않는, 순차적 일관성을 가진 가상의
 시스템에서도 일어날 수 있음을 기억해 두시기 바랍니다.
 
-다시 말하지만, 당신의 코드가 글로벌 이행성을 필요로 한다면, 범용 배리어를
-사용하십시오.
+다시 말하지만, 당신의 코드가 모든 오퍼레이션들의 완전한 순서를 필요로 한다면,
+범용 배리어를 사용하십시오.
 
 
 ==================
@@ -3046,6 +3041,9 @@ AMD64 Architecture Programmer's Manual Volume 2: System Programming
        Chapter 7.1: Memory-Access Ordering
        Chapter 7.4: Buffering and Combining Memory Writes
 
+ARM Architecture Reference Manual (ARMv8, for ARMv8-A architecture profile)
+       Chapter B2: The AArch64 Application Level Memory Model
+
 IA-32 Intel Architecture Software Developer's Manual, Volume 3:
 System Programming Guide
        Chapter 7.1: Locked Atomic Operations
@@ -3057,6 +3055,8 @@ The SPARC Architecture Manual, Version 9
        Appendix D: Formal Specification of the Memory Models
        Appendix J: Programming with the Memory Models
 
+Storage in the PowerPC (Stone and Fitzgerald)
+
 UltraSPARC Programmer Reference Manual
        Chapter 5: Memory Accesses and Cacheability
        Chapter 15: Sparc-V9 Memory Models