2017-09-11 2 views
2

어떤 이유로 든이 작업을 수행 할 수 없습니다 (코드 참조). 문서에서 보았다 ... 작동하지 이것에 대한 이유가std :: atomic 및 custom 구조체와 관련된 문제

struct vector { 
    float x, y, z; 
}; 
std::atomic<vector> Name = {0}; 

이하지 않는 것 그것은 내가 초기화 목록을 초기화 할 수 없습니다라고, 나는 그것을 사용에 갈 때 내 코드에 회원이 없다고 말합니다.

Name.x = 4.f; 
Name.y = 2.f * Name.x; 
Name.z = 0.1f; 

답변

-1

는 아무도이 내 능력 밖이지만, 어떤 얘기하지 왜 그것은하지 Name.x, Name.y, Name.z

Name._My_val.x, Name._My_val.y, Name._My_val.z입니다.

+0

아니요, 그렇지 않습니다.여기서하고있는 일은 내부 구현 세부 사항을 다루는 것입니다. 의도대로 작동하지 않습니다. –

+0

메모리 울타리를 건너 뜁니다. 이러한 작업은 원자 적이지 않습니다. –

+1

구조체를 원자 단위로 나누고 싶습니까, 아니면 전체 구조체를 단일 원자 단위로 사용 하시겠습니까? 어쨌든 이것은 12 바이트 구조체가 lock-free가 아닌 MSVC에서만 컴파일되므로 다른 원자 연산의 원 자성을 깨뜨릴 수 있습니다. https://godbolt.org/g/ji6ABT ** 다른 컴파일러에서도 컴파일되지 않습니다. ** –

3

std::atomic<vector>의 인스턴스 vector 인스턴스 아니다. x, y 또는 z이 없습니다. 그것이 가지고있는 것은 (개념적으로, 내부적으로) vector의 인스턴스입니다. 그러나 . 연산자를 사용하여 액세스 할 수 없습니다. 이는 원자 성을 깨뜨릴 수 있기 때문입니다 (예 : std::atomic). (이것은 당신이 초기화 목록을 사용할 수없는 이유이기도합니다.)

에서, vector 물건을 액세스 사용하려면 load()store() :

//atomically load a snapshot of Name 
auto name_snapshot = Name.load(); //name_snapshot is a vector instance 
name_snapshot.x = 4.f; 
name_snapshot.y = 2.f * name_snapshot.x; 
name_snapshot.z = 0.1f; 
//now atomically store it: 
Name.store(name_snapshot); 
+0

좋은'.load()'와'.store' 예제. 원자 RMW가 아니라는 것을 지적하는 것이 좋습니다. 당신은 CAS 루프를 사용해야 할 것입니다. 그것은 오직 원자 적로드이고 다른 스레드로부터의 업데이트를 밟을 수있는 무조건적인 (unconditional) 원자 저장소입니다. –

+0

또한 이니셜 라이저의 유일한 문제점은 중괄호 수준이 누락되었습니다.'std :: atomic Name = {{0,0,0}};'잘 컴파일됩니다 (https://godbolt.org/g/o5PdVF),'atomic '을 가지는 다른 방법은 그것의 [(비 원자) 생성자] (http://en.cppreference.com/w/cpp/atomic/atomic/atomic)에서'T 'std :: atomic Name2 {{1.0,1.0,2.0}}; ' –

+0

과 같은() 생성자를 다음과 같이 할 수 있을까요? 'Name.store ({0, 0, 0})'또는 실제 변수를 만들어야합니까? – vidsac

2

여기 std::atomic<> 있습니다 http://en.cppreference.com/w/cpp/atomic/atomic

에 대한 문서가있다 std::atomic<>에 회원 x, y 및 z가 없습니다.

std::atomic<X>전체가 X가 개별적으로는 아니고 원자 적으로 대체 될 수있는 유형입니다.

name_snapshot과 같은 구조에 대해 std :: atomic은 뮤텍스를 사용하므로 아마도 뮤텍스가 필요합니다. 사용 가능한 원자 적 지시가 될 가능성은 거의 없으므로 전체 구조의 원자 적재/저장을 처리하십시오.

+0

을 참조하십시오. 일부 컴파일러의 경우 x86-64를 대상으로하는 gcc 또는 clang과 같이 '원자 '은 T가 16 바이트까지 lock-free입니다. 그것은'.load()'또는'.store() '에 대해서도'lock cmpxchg16b'를 사용해야하는데, 그렇게 효율적이지는 않습니다. (그리고 이런 이유로, gcc7 이상은'.is_lock_free()'에 대해 false를 반환하고,''cmpxchg16b''를 인라인하지 않고 대신에 언제나 라이브러리 함수를 호출합니다 .https : //gcc.gnu.org/ml/ gcc-patches/2017-01/msg02344.html 현재의 라이브러리 구현은 lock-free이며,'lock cmpxchg16b' 인라인 코드와의 호환성을 깨지 않으면 서 변경할 수 없습니다. –