+=, |=, &= 등이 원자입니까?
"수정" 연산자는 다음과 같습니까?+=
,|=
,&=
원자력?
알고있어요++
is atomic (수행하는 경우)x++;
두 개의 다른 스레드에서 "simultane적으로" 당신은 항상 결국x
반대로 2가 증가했습니다.x=x+1
(최적화를 해제한 상태에서)
내가 궁금한 것은?variable |= constant
, 그런 것들은 실을 안전하게 보호해야 하나요 아니면 뮤텍스로 보호해야 하나요?
(...아니면 CPU 의존형입니까?이 경우 ARM에는 어떤 상태입니까?)
당신의 생각이 틀렸습니다.++가 원자라는 보장은 없으며, 복합 할당 연산자나 C++ 연산자에 대해서도 존재하지 않습니다.
x++
흔히 X를 레지스터로 읽고 증분한 다음 메모리에 다시 기록하는 세 가지 명령으로 구현됩니다.
당신의 스레드는 그들 중 어느 하나에 우선적으로 입력될 수 있습니다.
코어 간에 값의 변화가 나타나려면 +=(예를 들어) 값을 로드하고 증분을 추가한 다음 저장해야 합니다.이는 작업이 원자력 작업이 아님을 의미합니다.
원자성을 보장하려면 작업 주변에 적절한 잠금 장치를 설치해야 합니다.
C 또는 C++의 연산자는 원자가 될 수 없습니다.그들이 당신의 플랫폼에 있을지 모르지만, 당신은 확실히 알 수 없을 것입니다.일반적으로 원자가 되는 유일한 연산은 명령어 Test and Set로, 세마포어를 구현하기 위한 기본으로 어떤 형태로든 대부분의 최신 CPU에서 사용할 수 있습니다.
아니요, 원자력이 아닙니다!원시 유형에 대한 atomic 연산이 필요하고 Linux를 사용하는 경우 http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html 및/또는 atomic.h...
++ 컴파일러/플랫폼에서는 atomic일 수 있지만 c++ 사양에서는 atomic으로 정의되지 않습니다.
원자적인 방법으로 값을 수정하려면 창에서 Interlocked*와 같이 적절한 방법을 사용해야 합니다.
다른 모든 루틴들도 마찬가지입니다.원자 연산을 원할 경우 표준 연산이 아닌 적절한 호출을 사용해야 합니다.
컴파일러와 CPU 둘 다 의존적입니다.일부 명령어 세트는 기계 크기의 int에 대해 원자 명령어를 제공합니다.
그러나 컴파일러가 이러한 명령어를 사용한다는 보장은 없으며 코드를 스레드가 아닌 안전한 방법으로 최적화하지 않습니다.어셈블리에서 루틴을 작성하거나 원자성을 제공하는 컴파일러 특정 기술(예: instrinsics)을 사용하거나 이러한 기술 중 하나를 사용하는 라이브러리를 사용해야 합니다.
특히 ARM의 경우:ORR/ADD/AND 명령은 두 개의 피연산자를 사용하여 결과를 레지스터에 넣습니다.두 피연산자 모두 결과 레지스터와 동일한 레지스터가 될 수 있으므로 원자 |=, +=, &=로 사용할 수 있습니다.
물론 결과는 레지스터에 저장되고 첫 번째 피연산자도 레지스터에서 나와야 하므로 레지스터 로드가 원자적으로 수행되는지 확인해야 합니다.
모든 작업처럼 원자적이지 않을 뿐만 아니라 매우 흥미로운 결과를 얻을 수 있습니다.예를 들어, 컴파일러가 x에 쓰는 것을 본다면 레지스터나 스택 공간을 사용하는 것이 아니라 x를 임시 변수로 사용하는 것이 허용됩니다.이것은 x가 일시적으로 임의의 값을 포함할 수 있음을 의미하며, x에 합당한 값만 포함하는 것은 아닙니다.
http://software.intel.com/en-us/blogs/2013/01/06/benign-data-races-what-could-possibly-go-wrong
복제품이 여기로 전송되었으며 업데이트가 필요합니다."새로운" C11 언어는 다음을 인정하는 원자 속성을 가능하게 합니다.
_Atomic int a;
...
a += 3
는 (atomic) 무한 루프로 컴파일될 수 있습니다.선물 기준 감사합니다 여러분, 그러지 않으셨으면 좋았을 텐데요.
1: 일부 아키텍처에서 원자 연산은 특정 액세스 프로토콜을 지원하는 메모리에서만 가능합니다.예를 들어 ARMv7, MIPS는 시퀀스를 다음과 같이 바꿉니다.
do {
x = LoadLinked(a) + 3;
} while !StoreConditional(x, &a);
LoadLinked/StoreConditional은 일부 메모리/캐시 유형에 대해 정의되지 않았습니다.디버깅 재미있게 하세요.
2: 하위 블록이 아닌 캐시 라인(예: 32, 64, 256바이트)에서 작동하는 LoadLinked, StoreConditional의 아티팩트인 false sharing과 관련이 있습니다.따라서 _Atomic inta[4];는 a[n] 및 a[n+1]에서 동시 원자 작업을 안전하게 허용하기 위해 4* 캐시 라인 크기(따라서 1024바이트)가 필요할 수 있습니다. 왜냐하면 4개의 CPU가 a[0..3] 업데이트와 싸울 수 있지만 성공하지 못했기 때문입니다.
바라건대 다음 표준은 속성 장식의 고유한 실패를 인식하고 c89를 올바른 C 표준으로 복원할 것입니다.
이 연산자들은 과부하가 걸릴 수 있기 때문에 모든 계층에 대해 원자력이라는 일반적인 보장이 있을 수 없다는 점을 언급할 필요가 있습니다.
라 할지라도++
원자 연산인데, 두 개의 스레드가++x
결과적으로x
정확히 두 명이 더 높은 거죠어떻게든 스레드를 동기화해야 합니다. 그렇지 않으면 스레드가 서로의 변경 사항을 볼 수 없습니다.
예를 들어, 뮤텍스를 사용하여 변수를 보호해야 합니다.
언급URL : https://stackoverflow.com/questions/2468857/are-etc-atomic
'programing' 카테고리의 다른 글
Angularjs 필터 네거티브 (0) | 2023.10.23 |
---|---|
CSS 센터 디스플레이 인라인 블록? (0) | 2023.10.23 |
MS Visual Studio 컴파일러에서 사용할 수 있는 C99 기능은 무엇입니까? (0) | 2023.10.18 |
여러 테이블에서 조인과 선택 간의 성능 차이? (0) | 2023.10.18 |
개발자용 PowerShell (0) | 2023.10.18 |