오픈 소스 소프트웨어 프로젝트에서 gcc atomic builtins : __sync_add_and_fetch 및 __sync_sub_and_fetch를 호출하여 특정 변수에 대한 원자 증분 및 감소를 구현합니다. 나는 정기적으로 내 코드를 컴파일하려고 누군가로부터 이메일을 얻을 수 있지만, 다음과 같은 링커 오류 얻을 : 뒷조사 후__sync_add_and_fetch가 정의되지 않음
refcountobject.cpp:(.text+0xb5): undefined reference to `__sync_sub_and_fetch_4'
refcountobject.cpp:(.text+0x115): undefined reference to `__sync_add_and_fetch_4'
을, 나는 사실 근본 원인을 좁혀 그 GCC 자신의 이전 버전 (4.1) 기본값은 i386의 대상 아키텍처입니다. 그리고 분명히 gcc는 실제로 80386에 원자 추가 기능을위한 내장 함수를 가지고 있지 않으므로 암시 적으로 정의되지 않은 __sync_add_and_fetch_4 호출을 여기에 삽입합니다. 이 작동 방식에 대한 훌륭한 설명은 here입니다.
here으로 설명한 쉬운 해결 방법은 컴파일러 플래그 중 하나로 -march = pentium을 추가하도록 Makefile을 수정하도록 알려주는 것입니다. 그리고 모두 좋다.
사용자가 직접 Makefile을 수정하지 않아도되는 장기적인 수정 사항은 무엇입니까?
내가 고려하고 몇 가지 아이디어 :
나는 메이크로 컴파일러 플래그로 = 펜티엄를 -march 하드 코드 싶지 않아요. 나는 그것이 인텔 기반이 아닌 것을 망칠 것이라고 추측하고있다. 그러나 Makefile에 기본 대상이 i386이라는 것을 감지하는 규칙이있는 경우 확실히 추가 할 수있었습니다. 나는 Makefile에서 gcc -dumpmachine을 호출하고 첫 번째 삼중 항을 분석하는 스크립트 인 규칙을 생각하고있다. 문자열이 i386이면 컴파일러 플래그를 추가합니다. 아무도 실제로 80386 머신을 만들지 않을 것이라고 가정합니다.
다른 대안은 링커가 다시 사용하도록 __sync_add_and_fetch_4에 대한 구현을 실제로 제공하는 것입니다. 그것은 정의되고있는 GCC_HAVE_SYNC_COMPARE_AND_SWAP 매크로의 존재를 기반으로 조건부로 컴파일 될 수도 있습니다. 필자는 전역 pthread_mutex를 사용하여 구현을 프로토 타이핑했다. 가장 좋은 성능은 아닐지 모르지만 작동하고 문제를 훌륭하게 해결합니다. x86 용으로 컴파일하는 경우 구현을 위해 "lock xadd"를 호출하는 인라인 어셈블리를 직접 작성하는 것이 더 좋은 아이디어 일 수 있습니다.
코드에서 값이 오버플로되면 조건 플래그가 발생하지 않는다고 잘못 가정합니다. clobbered register리스트에'cc '를 추가하십시오. –