diff options
author | SeongJae Park <sj38.park@gmail.com> | 2017-03-03 01:44:02 -0500 |
---|---|---|
committer | Jonathan Corbet <corbet@lwn.net> | 2017-03-03 17:54:55 -0500 |
commit | 9857b1ad4740ec2429e8ec0a39946d45a8d2cff9 (patch) | |
tree | 477c842f018e6ef6a7d0d43eb7d8674181dbfa3e | |
parent | 2eb6a4b26d13c51bdb8d5aefdfc846c0624b8ce4 (diff) |
doc/ko_KR/memory-barriers: Update control-dependencies section
This commit applies upstream change, commit c8241f8553e8 ("doc: Update
control-dependencies section of memory-barriers.txt"), to Korean
translation.
Signed-off-by: SeongJae Park <sj38.park@gmail.com>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
-rw-r--r-- | Documentation/translations/ko_KR/memory-barriers.txt | 68 |
1 files changed, 37 insertions, 31 deletions
diff --git a/Documentation/translations/ko_KR/memory-barriers.txt b/Documentation/translations/ko_KR/memory-barriers.txt index a3228a676cc1..ce0b48d69eaa 100644 --- a/Documentation/translations/ko_KR/memory-barriers.txt +++ b/Documentation/translations/ko_KR/memory-barriers.txt | |||
@@ -662,6 +662,10 @@ include/linux/rcupdate.h 의 rcu_assign_pointer() 와 rcu_dereference() 를 | |||
662 | 컨트롤 의존성 | 662 | 컨트롤 의존성 |
663 | ------------- | 663 | ------------- |
664 | 664 | ||
665 | 현재의 컴파일러들은 컨트롤 의존성을 이해하고 있지 않기 때문에 컨트롤 의존성은 | ||
666 | 약간 다루기 어려울 수 있습니다. 이 섹션의 목적은 여러분이 컴파일러의 무시로 | ||
667 | 인해 여러분의 코드가 망가지는 걸 막을 수 있도록 돕는겁니다. | ||
668 | |||
665 | 로드-로드 컨트롤 의존성은 데이터 의존성 배리어만으로는 정확히 동작할 수가 | 669 | 로드-로드 컨트롤 의존성은 데이터 의존성 배리어만으로는 정확히 동작할 수가 |
666 | 없어서 읽기 메모리 배리어를 필요로 합니다. 아래의 코드를 봅시다: | 670 | 없어서 읽기 메모리 배리어를 필요로 합니다. 아래의 코드를 봅시다: |
667 | 671 | ||
@@ -689,20 +693,21 @@ CPU 는 b 로부터의 로드 오퍼레이션이 a 로부터의 로드 오퍼레 | |||
689 | 693 | ||
690 | q = READ_ONCE(a); | 694 | q = READ_ONCE(a); |
691 | if (q) { | 695 | if (q) { |
692 | WRITE_ONCE(b, p); | 696 | WRITE_ONCE(b, 1); |
693 | } | 697 | } |
694 | 698 | ||
695 | 컨트롤 의존성은 보통 다른 타입의 배리어들과 짝을 맞춰 사용됩니다. 그렇다곤 | 699 | 컨트롤 의존성은 보통 다른 타입의 배리어들과 짝을 맞춰 사용됩니다. 그렇다곤 |
696 | 하나, READ_ONCE() 는 반드시 사용해야 함을 부디 명심하세요! READ_ONCE() 가 | 700 | 하나, READ_ONCE() 도 WRITE_ONCE() 도 선택사항이 아니라 필수사항임을 부디 |
697 | 없다면, 컴파일러가 'a' 로부터의 로드를 'a' 로부터의 또다른 로드와, 'b' 로의 | 701 | 명심하세요! READ_ONCE() 가 없다면, 컴파일러는 'a' 로부터의 로드를 'a' 로부터의 |
698 | 스토어를 'b' 로의 또다른 스토어와 조합해 버려 매우 비직관적인 결과를 초래할 수 | 702 | 또다른 로드와 조합할 수 있습니다. WRITE_ONCE() 가 없다면, 컴파일러는 'b' 로의 |
699 | 있습니다. | 703 | 스토어를 'b' 로의 또라느 스토어들과 조합할 수 있습니다. 두 경우 모두 순서에 |
704 | 있어 상당히 비직관적인 결과를 초래할 수 있습니다. | ||
700 | 705 | ||
701 | 이걸로 끝이 아닌게, 컴파일러가 변수 'a' 의 값이 항상 0이 아니라고 증명할 수 | 706 | 이걸로 끝이 아닌게, 컴파일러가 변수 'a' 의 값이 항상 0이 아니라고 증명할 수 |
702 | 있다면, 앞의 예에서 "if" 문을 없애서 다음과 같이 최적화 할 수도 있습니다: | 707 | 있다면, 앞의 예에서 "if" 문을 없애서 다음과 같이 최적화 할 수도 있습니다: |
703 | 708 | ||
704 | q = a; | 709 | q = a; |
705 | b = p; /* BUG: Compiler and CPU can both reorder!!! */ | 710 | b = 1; /* BUG: Compiler and CPU can both reorder!!! */ |
706 | 711 | ||
707 | 그러니 READ_ONCE() 를 반드시 사용하세요. | 712 | 그러니 READ_ONCE() 를 반드시 사용하세요. |
708 | 713 | ||
@@ -712,11 +717,11 @@ CPU 는 b 로부터의 로드 오퍼레이션이 a 로부터의 로드 오퍼레 | |||
712 | q = READ_ONCE(a); | 717 | q = READ_ONCE(a); |
713 | if (q) { | 718 | if (q) { |
714 | barrier(); | 719 | barrier(); |
715 | WRITE_ONCE(b, p); | 720 | WRITE_ONCE(b, 1); |
716 | do_something(); | 721 | do_something(); |
717 | } else { | 722 | } else { |
718 | barrier(); | 723 | barrier(); |
719 | WRITE_ONCE(b, p); | 724 | WRITE_ONCE(b, 1); |
720 | do_something_else(); | 725 | do_something_else(); |
721 | } | 726 | } |
722 | 727 | ||
@@ -725,12 +730,12 @@ CPU 는 b 로부터의 로드 오퍼레이션이 a 로부터의 로드 오퍼레 | |||
725 | 730 | ||
726 | q = READ_ONCE(a); | 731 | q = READ_ONCE(a); |
727 | barrier(); | 732 | barrier(); |
728 | WRITE_ONCE(b, p); /* BUG: No ordering vs. load from a!!! */ | 733 | WRITE_ONCE(b, 1); /* BUG: No ordering vs. load from a!!! */ |
729 | if (q) { | 734 | if (q) { |
730 | /* WRITE_ONCE(b, p); -- moved up, BUG!!! */ | 735 | /* WRITE_ONCE(b, 1); -- moved up, BUG!!! */ |
731 | do_something(); | 736 | do_something(); |
732 | } else { | 737 | } else { |
733 | /* WRITE_ONCE(b, p); -- moved up, BUG!!! */ | 738 | /* WRITE_ONCE(b, 1); -- moved up, BUG!!! */ |
734 | do_something_else(); | 739 | do_something_else(); |
735 | } | 740 | } |
736 | 741 | ||
@@ -742,10 +747,10 @@ CPU 는 b 로부터의 로드 오퍼레이션이 a 로부터의 로드 오퍼레 | |||
742 | 747 | ||
743 | q = READ_ONCE(a); | 748 | q = READ_ONCE(a); |
744 | if (q) { | 749 | if (q) { |
745 | smp_store_release(&b, p); | 750 | smp_store_release(&b, 1); |
746 | do_something(); | 751 | do_something(); |
747 | } else { | 752 | } else { |
748 | smp_store_release(&b, p); | 753 | smp_store_release(&b, 1); |
749 | do_something_else(); | 754 | do_something_else(); |
750 | } | 755 | } |
751 | 756 | ||
@@ -754,10 +759,10 @@ CPU 는 b 로부터의 로드 오퍼레이션이 a 로부터의 로드 오퍼레 | |||
754 | 759 | ||
755 | q = READ_ONCE(a); | 760 | q = READ_ONCE(a); |
756 | if (q) { | 761 | if (q) { |
757 | WRITE_ONCE(b, p); | 762 | WRITE_ONCE(b, 1); |
758 | do_something(); | 763 | do_something(); |
759 | } else { | 764 | } else { |
760 | WRITE_ONCE(b, r); | 765 | WRITE_ONCE(b, 2); |
761 | do_something_else(); | 766 | do_something_else(); |
762 | } | 767 | } |
763 | 768 | ||
@@ -770,10 +775,10 @@ CPU 는 b 로부터의 로드 오퍼레이션이 a 로부터의 로드 오퍼레 | |||
770 | 775 | ||
771 | q = READ_ONCE(a); | 776 | q = READ_ONCE(a); |
772 | if (q % MAX) { | 777 | if (q % MAX) { |
773 | WRITE_ONCE(b, p); | 778 | WRITE_ONCE(b, 1); |
774 | do_something(); | 779 | do_something(); |
775 | } else { | 780 | } else { |
776 | WRITE_ONCE(b, r); | 781 | WRITE_ONCE(b, 2); |
777 | do_something_else(); | 782 | do_something_else(); |
778 | } | 783 | } |
779 | 784 | ||
@@ -781,7 +786,7 @@ CPU 는 b 로부터의 로드 오퍼레이션이 a 로부터의 로드 오퍼레 | |||
781 | 위의 코드를 아래와 같이 바꿔버릴 수 있습니다: | 786 | 위의 코드를 아래와 같이 바꿔버릴 수 있습니다: |
782 | 787 | ||
783 | q = READ_ONCE(a); | 788 | q = READ_ONCE(a); |
784 | WRITE_ONCE(b, p); | 789 | WRITE_ONCE(b, 1); |
785 | do_something_else(); | 790 | do_something_else(); |
786 | 791 | ||
787 | 이렇게 되면, CPU 는 변수 'a' 로부터의 로드와 변수 'b' 로의 스토어 사이의 순서를 | 792 | 이렇게 되면, CPU 는 변수 'a' 로부터의 로드와 변수 'b' 로의 스토어 사이의 순서를 |
@@ -793,10 +798,10 @@ CPU 는 b 로부터의 로드 오퍼레이션이 a 로부터의 로드 오퍼레 | |||
793 | q = READ_ONCE(a); | 798 | q = READ_ONCE(a); |
794 | BUILD_BUG_ON(MAX <= 1); /* Order load from a with store to b. */ | 799 | BUILD_BUG_ON(MAX <= 1); /* Order load from a with store to b. */ |
795 | if (q % MAX) { | 800 | if (q % MAX) { |
796 | WRITE_ONCE(b, p); | 801 | WRITE_ONCE(b, 1); |
797 | do_something(); | 802 | do_something(); |
798 | } else { | 803 | } else { |
799 | WRITE_ONCE(b, r); | 804 | WRITE_ONCE(b, 2); |
800 | do_something_else(); | 805 | do_something_else(); |
801 | } | 806 | } |
802 | 807 | ||
@@ -828,35 +833,33 @@ CPU 는 b 로부터의 로드 오퍼레이션이 a 로부터의 로드 오퍼레 | |||
828 | 833 | ||
829 | q = READ_ONCE(a); | 834 | q = READ_ONCE(a); |
830 | if (q) { | 835 | if (q) { |
831 | WRITE_ONCE(b, p); | 836 | WRITE_ONCE(b, 1); |
832 | } else { | 837 | } else { |
833 | WRITE_ONCE(b, r); | 838 | WRITE_ONCE(b, 2); |
834 | } | 839 | } |
835 | WRITE_ONCE(c, 1); /* BUG: No ordering against the read from "a". */ | 840 | WRITE_ONCE(c, 1); /* BUG: No ordering against the read from 'a'. */ |
836 | 841 | ||
837 | 컴파일러는 volatile 타입에 대한 액세스를 재배치 할 수 없고 이 조건 하의 "b" | 842 | 컴파일러는 volatile 타입에 대한 액세스를 재배치 할 수 없고 이 조건 하의 'b' |
838 | 로의 쓰기를 재배치 할 수 없기 때문에 여기에 순서 규칙이 존재한다고 주장하고 | 843 | 로의 쓰기를 재배치 할 수 없기 때문에 여기에 순서 규칙이 존재한다고 주장하고 |
839 | 싶을 겁니다. 불행히도 이 경우에, 컴파일러는 다음의 가상의 pseudo-assembly 언어 | 844 | 싶을 겁니다. 불행히도 이 경우에, 컴파일러는 다음의 가상의 pseudo-assembly 언어 |
840 | 코드처럼 "b" 로의 두개의 쓰기 오퍼레이션을 conditional-move 인스트럭션으로 | 845 | 코드처럼 'b' 로의 두개의 쓰기 오퍼레이션을 conditional-move 인스트럭션으로 |
841 | 번역할 수 있습니다: | 846 | 번역할 수 있습니다: |
842 | 847 | ||
843 | ld r1,a | 848 | ld r1,a |
844 | ld r2,p | ||
845 | ld r3,r | ||
846 | cmp r1,$0 | 849 | cmp r1,$0 |
847 | cmov,ne r4,r2 | 850 | cmov,ne r4,$1 |
848 | cmov,eq r4,r3 | 851 | cmov,eq r4,$2 |
849 | st r4,b | 852 | st r4,b |
850 | st $1,c | 853 | st $1,c |
851 | 854 | ||
852 | 완화된 순서 규칙의 CPU 는 "a" 로부터의 로드와 "c" 로의 스토어 사이에 어떤 | 855 | 완화된 순서 규칙의 CPU 는 'a' 로부터의 로드와 'c' 로의 스토어 사이에 어떤 |
853 | 종류의 의존성도 갖지 않을 겁니다. 이 컨트롤 의존성은 두개의 cmov 인스트럭션과 | 856 | 종류의 의존성도 갖지 않을 겁니다. 이 컨트롤 의존성은 두개의 cmov 인스트럭션과 |
854 | 거기에 의존하는 스토어 에게만 적용될 겁니다. 짧게 말하자면, 컨트롤 의존성은 | 857 | 거기에 의존하는 스토어 에게만 적용될 겁니다. 짧게 말하자면, 컨트롤 의존성은 |
855 | 주어진 if 문의 then 절과 else 절에게만 (그리고 이 두 절 내에서 호출되는 | 858 | 주어진 if 문의 then 절과 else 절에게만 (그리고 이 두 절 내에서 호출되는 |
856 | 함수들에게까지) 적용되지, 이 if 문을 뒤따르는 코드에는 적용되지 않습니다. | 859 | 함수들에게까지) 적용되지, 이 if 문을 뒤따르는 코드에는 적용되지 않습니다. |
857 | 860 | ||
858 | 마지막으로, 컨트롤 의존성은 이행성 (transitivity) 을 제공하지 -않습니다-. 이건 | 861 | 마지막으로, 컨트롤 의존성은 이행성 (transitivity) 을 제공하지 -않습니다-. 이건 |
859 | x 와 y 가 둘 다 0 이라는 초기값을 가졌다는 가정 하의 두개의 예제로 | 862 | 'x' 와 'y' 가 둘 다 0 이라는 초기값을 가졌다는 가정 하의 두개의 예제로 |
860 | 보이겠습니다: | 863 | 보이겠습니다: |
861 | 864 | ||
862 | CPU 0 CPU 1 | 865 | CPU 0 CPU 1 |
@@ -924,6 +927,9 @@ http://www.cl.cam.ac.uk/users/pes20/ppc-supplemental/test6.pdf 와 | |||
924 | (*) 컨트롤 의존성은 이행성을 제공하지 -않습니다-. 이행성이 필요하다면, | 927 | (*) 컨트롤 의존성은 이행성을 제공하지 -않습니다-. 이행성이 필요하다면, |
925 | smp_mb() 를 사용하세요. | 928 | smp_mb() 를 사용하세요. |
926 | 929 | ||
930 | (*) 컴파일러는 컨트롤 의존성을 이해하고 있지 않습니다. 따라서 컴파일러가 | ||
931 | 여러분의 코드를 망가뜨리지 않도록 하는건 여러분이 해야 하는 일입니다. | ||
932 | |||
927 | 933 | ||
928 | SMP 배리어 짝맞추기 | 934 | SMP 배리어 짝맞추기 |
929 | -------------------- | 935 | -------------------- |