smart pointer (RAII)
- 객체의 생성 소멸 관리를 위해 사용하는 객체
- shared_ptr<T>, unique_ptr<T>
t_ptr<T>
- shared_ptr<T>처럼 Reference Count를 공유
- 침습형(invasive) 카운터를 사용
Cppcon2015 중
"Smart pointers" are overused (스마트 포인터는 과다 사용되고 있다)
- shared_ptr can be expensive => reference count의 증감 연산이 많이 일어나기 때문에
사례1) 빠른줄만 알았던 type_cast
template<typename T, typename S>
T* type_cast<T>(S* s)
{
if (s && TypeTable<Idx<S>][Idx<T>])
{
return static_cast<T>(s);
}
return nullptr;
}
template<typename T, typename S>
t_ptr<T> type_cast<T>(t_ptr<S> s)
{ <29.9%
if (s && TypeTable<Idx<S>][Idx<T>])
{
return static_cast<T>(s);
} <70.0%
return nullptr;
}
// 뜻 밖의 복사생성자와 소멸자가 호출
// t_ptr<S>와 t_ptr<T>를 & 또는 && 형으로 변경
사례 2) 빠른줄만 알았던 Vector
주위에 있는 GameObject의 t_ptr을 Vector에 저장하는데 느려진다 => Reallocation에서 RefCount++/--가 일어나는걸 확인
Vector Reallocation (push_back)
이를 방지하기 위해 Move Semantics 사용
생성자난 대입연산자가 Rvalue를 사용할 땐 '소유권'을 넘겨주는 것만으로 충분하다
Object(Object&& other) {
mChile = other.mChild;
other.mChild = nullptr;
}
Object(Object& other) {
DeepCopy(mChild, other.mChild);
}
variadic template and some practical techniques (변수 템플릿과 몇 가지 실용적인 기술)
Variadic Template
- 임의의 인자 개수를 지원하는 템플릿 형식(클래스, 함수 모두 지원)
- Ellipsis operator(...)와 함께 사용 => arguments, paramters, sizeof op, initializer list of array, member initializer list, lambda capture, exception specification list
먼 과거
template<class Type, class Arg1, class Arg2, class Arg3>
Type* tnew(Arg1 arg1, Arg2 arg2, Arg3, arg3)
{
Type* memory = (Type*)AllocMemory(sizeof(Type));
new(memory) Type(arg1, arg2, arg3);
return (Type*)memory;
}
과거
#define MEMORY_ALLOC_ARG_NUM 40
#define MEORY_tnew_print(z, n, _) \
template<class Type BOOST_PP_COMMA_IF(n) BOOST_PP_ENUM_PARAMS(n, class Arg)> \
Type* tnew(BOOST_PP_ENUM_BINARY_PARAMS(n, Arg, arg)) \
{ \
Type* memory = (Type*)AllocMemory(sizeof(Type)); \
new(memory) Type(BOOST_PP_ENUM_PARAMS(n, arg));\
return memory; \
} \
BOOST_PP_REPEAT(BOOST_PP_INC(MEMORY_ALLOC_ARG_NUM(, MEMORY_tenw_print, _)
현재
template<class Type, class... Args>
Type* tnew(Args&&... args)
{
Type* memory = (Type*)AllocMemory(sizeof(Type));
new(memory)Type(forward<Args>(args)...);
return memory;
}
튜플의 각 원소들에 대해서 함수를 수행하고 싶고, 함수의 인자로도 사용하고 싶다
Integer_sequence
template<int... Remains>
struct req{};
template<int N, int... Remains>
struct gen_seq : gen_seq <N-1, N-1, Remains...> {};
template<int N, int... Remains>
struct gen_seq<0, Remains...> : seq <Remains...> {};
gen_seq<3> -> <2, 2> -> <1, 1, 2> -> <0, 0, 1, 2> -> seq<0, 1, 2>
* C++14부턴 간단하게 std::make_index_sequence<N>으로 대체 가능
C++ 11/14 비동기 키워드
std::thread
std::thread t(&func, 3);
std::thread t2([] { printf("f"); });
t.join();
t2.join();
std::promise / std::future
promise<int> prom;
future<int> fut = prom.get_future();
auto t = thread[&]{ prom.set_value(1); });
cout << fut.get << endl;
t.join();
std::async
auto myFuture = async(launch::async, &foo, 1.0);
cout << myFuture.get() << endl;
// original
bool result = true;
for (auto& job : jobList) {
if (job.Execute() == false)
return = false;
}
// distribution
bool result = true;
vector<future<bool>> futures;
for (auto& job : jobList) {
futures.push_back(
async(lanuch:async, [&] { job.Execute(); }));
}
for (const auto& fut : futures) {
if (fut.get() == false)
result = false;
}
출처: http://ndcreplay.nexon.com/NDC2016/sessions/NDC2016_0066.html
'NDC > Server' 카테고리의 다른 글
[NDC 2016] <야생의 땅: 듀랑고> 중앙 서버 없는 게임 로직 (0) | 2023.01.16 |
---|---|
[NDC 2016] <야생의 땅: 듀랑고> 지형 관리 완전 자동화 - AWS와 DOCKER 체험기 (0) | 2023.01.15 |
[NDC 2016] UDP를 사용해서 게임 서버 만들기 (0) | 2023.01.10 |
[NDC 2015] <쿠키런> 바쁘고 가난한 개발자를 위한 S3 기반 로그 시스템 (0) | 2023.01.05 |
[NDC 2015] 피파온라인3 서버 구조와 85만 동접 포스트 모템 (0) | 2023.01.05 |