Optimization Tips - Andrei Alexandrescu - CppCon 2014
Optimization Tips - Andrei Alexandrescu - CppCon 2014
--max-inline-instns-auto=100
--early-inlining-instns=200
I-Cache
// GCC
#define ALWAYS_INLINE inline __attribute__((__always_inline__))
#define NEVER_INLINE __attribute__((__noinline__))
// VC++:
#define ALWAYS_INLINE __forceinline
#define NEVER_INLINE __declspec(noinline)
Defang NEVER_INLINE
Defang ALWAYS_INLINE
SingleThreadPtr(SingleThreadPtr&& rhs)
: p_(rhs.p_)
, c_(rhs.c_) {
rhs.p_ = nullptr;
rhs.c_ = nullptr;
}
~SingleThreadPtr() {
if (c_ && --*c_ == 0) {
delete p_;
delete c_;
}
}
• Focus on MT
• Use atomic<unsigned>* for c_
• Use fetch_add(1,memory_order_relaxed)
for ++
• fetch_sub(1,memory_order_acq_rel) for --
Task
Observation
Tip #2 (cont’d)
...
SingleThreadPtr(SingleThreadPtr&& rhs)
: p_(rhs.p_)
, c_(rhs.c_) {
rhs.p_ = nullptr;
//rhs.c_ = nullptr; // UNNEEDED
}
~SingleThreadPtr() {
if (!p_) return;
if (!c_) {
soSueMe: delete p_;
} else if (--*c_ == 0) {
delete c_;
goto soSueMe;
}
}
...
SingleThreadPtr(SingleThreadPtr&& rhs)
: p_(rhs.p_)
, c_(rhs.c_) {
rhs.p_ = nullptr;
rhs.c_ = nullptr; // NEEDED
}
~SingleThreadPtr() {
if (!c_) {
soSueMe: delete p_;
} else if (--*c_ == 0) {
delete c_;
goto soSueMe;
}
}
Performance Dynamics
Motivation
...
SingleThreadPtr(const SingleThreadPtr& rhs)
: p_(rhs.p_)
, c_(rhs.c_) {
if (!p_) return;
if (!c_) {
c_ = rhs.c_ = new unsigned(1);
} else {
++*c_;
}
}
...
...
~SingleThreadPtr() {
if (!p_) return;
if (!c_) {
soSueMe: delete p_;
} else if (*c_ == 0) {
delete c_;
goto soSueMe;
} else {
--*c_;
}
}
...