C++ 16

True sharing / False sharing : std::hardware_..._interference_size

True sharing / False sharing : std::hardware_..._interference_size 1. 설명 False sharing은 2개 이상의 코어가 서로 다른 메모리 주소에 접근하지만, 두 주소가 동일한 캐시 최소 단위에 적제되어 있어(논리적으로는 전혀 영향이 없지만 캐시는 이를 모르기에) 동기화가 이루어져 성능이 하락하는것을 말합니다. True sharing은 false sharing과는 반대로 동일한 메모리 주소에 값을 쓸때를 의미합니다. 이때는 당연히 동기화가 이루어지기에(논리적으로도 그것이 맞고) 이번글에서는 딱히 다루지 않겠습니다. C++17 에는 이렇게 동일한 캐시라인에 적제되는지 판별할수 있는(L1 캐시 라인 크기를 얻어오는) 표준이 추가되었습니다. 다만, 아직까..

C++/개념(Concept) 2021.08.30

Tensorflow Lite 를 C/C++로 빌드하기(bazel)

Tensorflow Lite 를 C/C++로 빌드하기(bazel) 1. Tensorflow Lite 다운로드 Tensorflow 공식 GitHub에 접속한 후, Release 탭에서 원하는 버전을 다운받습니다. https://github.com/tensorflow/tensorflow/releases Releases · tensorflow/tensorflow An Open Source Machine Learning Framework for Everyone - tensorflow/tensorflow github.com 여기서는 현재(2021.08.29)의 최신버전인 2.4.3을 사용하겠습니다. 제가 기억하기로는 1.X 부터 현재까지 빌드하는방법은 모두 동일한것으로 기억합니다. 혹시 본 글대로 했는데 에러가 ..

[BUG Report] MSVC(C++20) Closure type's special member function

마이크로소프트 컴파일러 C++20 feature 버그 1. 서론 C++20 에서 Closure type 이 이제 캡처가 없는 경우 특수 멤버 함수(기본 생성, 복사/이동 연산)를 제공하게 되었습니다. 여기서, 캡처가 없다는것은 실제로 내부에선 캡처된 객체를 사용하지 않더라도, 무조건 코드상에 캡처가 표시가 되어있는가를 기준으로 판단되어집니다. Proposal cppreference expr.prim.lambda_closure 2. 예시 int x = 1; auto lambda1 = []() { return 1; }; auto lambda2 = [&]() { return x; }; auto lambda3 = [&]() { return 1; }; 위에서 말했듯이, 실제 내부적으로 캡처된것이 사용되는지의 여부..

deleted 함수와 이동 연산의 overload resolution

deleted 함수와 이동 연산의 overload resolution 1. 설명 특수 멤버 함수는 경우에 따라 암시적으로 자동생성되지 않을 수도 있고, 혹은 명시적으로 삭제할수도 있습니다. 이러한 두 경우에 따라서 이동 연산(이동 생성, 이동 대입)이 overload 에 참여할 수도, 참여하지 않을 수도 있습니다. 그러면 경우에 따라 이동을 의도했지만 실제로는 복사가 일어나게 될 수 있으며, 성능 저하(대게는 프로그래머가 의도하지 않은)가 일어날 수 있습니다. 본 글에서는 편의를 위해 암시적으로 자동생성되지 않은 경우를 암시적 삭제로 부르도록 하겠습니다. 2. 예시 우선, 객체가 trivial 한 복사 및 이동연산을 지원한다면, 이동 연산은 무조건 복사 연산으로 대체됩니다. 사실 당연한 것입니다. tri..

C++/개념(Concept) 2021.05.30

C/C++ 개념: 전방 선언(forward declaration)

전방 선언(forward declaration) 1. 설명 함수나, 구조체, 열거자, 공용자, 외부(extern) 변수 (C++ 에서는 클래스도) 등을 그 실제 구현(implementation) 시점보다 앞서서 선언(declare)만 하는 것을 말합니다. 물론, 구현부와 선언부의 서명(signature)은 일치해야 합니다. 서로를 호출하는 함수, 외부(extern) 변수, PImple 기법 등에서 사용됩니다. 헤더와 소스 파일로 구현부, 선언부를 분리하는 행위는 기본적으로 모두 전방 선언에 속합니다. ※ main 함수보다 아래에서 구현된 함수를 호출할 때도 main 위에서 해당 함수를 전방 선언해야 합니다. 하지만 이런 케이스는 그냥 해당 함수를 main 위로 옮기면 되는 거라(원래는 다른 헤더 파일로 ..

C/C++ 개념: 완전한 타입(Complete Type), 불완전한 타입(Incomplete Type)

완전한 타입(Complete Type), 불완전한 타입(Incomplete Type) 1. 설명 완전한 타입이란, 해당 컴파일 시점에서 그 타입(구조체(struct), 열거자(enum), 공용체(union), 클래스(class))의 구현(Implement) 정보를 모두 알고 있는 타입을 말합니다. 위 4가지를 제외한 모든 타입은 무조건 완전한 타입입니다. 불완전한 타입이란, 해당 컴파일 시점에서 그 타입의 구현 정보를 알지 못하고, 선언된 정보만 알고 있는 상태를 말합니다. ※ 타입의 어떠한 정보도 알지 못하는건 그냥 알수 없는 타입(unknown type)이나 알수 없는 식별자(unknown identifier) 입니다. 보통 실수로 헤더를 넣지 않거나 했을 때 생깁니다. 2. 예시 #include s..

C++ 디자인: PImpl

C++ 디자인(Design): PImpl (Pointer to Implement) 1. 설명 Pimple 디자인은 헤더 파일에서는 실제 구현을 담당하는 클래스를 불완전한 타입으로 선언하고 이에 대한 포인터만 원래 클래스에 남겨두고, 소스 파일에서 구현 클래스를 정의하는 방법입니다. 그래서 Pointer to Implementation (구현(클래스)에 대한 포인터)라는 이름이 붙게 되었습니다. 이로 인해서 얻는 장점은 크게 2가지가 있습니다. 1. 컴파일 시간 단축 / ABI 호환성 보장 내부 구현이 바뀌어도, 헤더만 참조하는 파일은 재 컴파일이 필요하지 않음 2. 소스 코드 은닉 소스 파일을 빌드해서 배포할 시, 소스 코드를 은닉할 수 있습니다. 다만, 구현 클래스가 템플릿 특수화된 클래스거나, 팩토리..

C++ 템플릿(Template): SFINAE

C++ Template: SFINAE Substitution Failure Is Not An Error SFINAE는 C++ 템플릿 프로그래밍에서 자주 쓰이는 기법입니다. 컴파일러가 알맞은 함수를 추론(deduce) 하는 원리를 이용해, 받는 타입을 제한하거나 타입에 따라 행동을 다르게 할 때 주로 사용하게 됩니다. SFINAE is a technique that is often used in C++ Template Programming. It restrains function parameter types by using the mechanism of how the compiler deduces appropriate overloaded functions and calling the appropriate ..