2017年1月21日 星期六

The Speed Game: Automated Trading Systems in C++

https://meetingcpp.com/index.php/tv16/items/18.html



C++ low latency coding techniques:

● General considerations

C++11 Move semantics
Static assert
Data member layout, padding and alignment (盡量alignment access)
● False sharing
http://shuyufu.blogspot.tw/2013/01/false-sharing.html
● Cache locality

● Compile-time dispatch

std::sort(array, array + N, [](int a, int b) { return b < a; });
 71us, std deviation 1.5us

int comparer(const void* a, const void* b) { return *(int*)a - *(int*)b; } qsort(arr, N, sizeof(int), comparer); 223us, std deviation 7us

● Constexpr
C++14 feature
● Variadic templates
● Loop unrolling
Generally, don’t bother, the compiler will figure it out
● Expression short-circuiting

Rewrite:
if (expensiveCheck() && inexpensiveCheck()) {}
As:
if (inexpensiveCheck() && expensiveCheck()) {}

● Signed vs unsigned comparisons
用loop iteratort用signed就是了 (可看前篇

● Mixing float and doubles

Default type of a floating point literal in C++ is double, not float
Side note: If you are brave, consider -ffast-math

● Branch prediction/reduction
Compile-time branch prediction hints are a topic of much discussion (particularly within SG14)
○ I.e. gcc’s __builtin_expect

Avoid this:
 if (checkForErrorA()) handleErrorA();
 else if (checkForErrorB()) handleErrorB();
 else if (checkForErrorC()) handleErrorC();
 else executeHotpath();

Aim for this:
 uint32_t errorFlags; ...
 if (errorFlags) HandleError(errorFlags)
 else { ... hotpath }

● Exceptions
不要用

● Slowpath removal
Code is data - keep it minimal, and keep the slowpath code away from the hotpath

● Avoiding allocations
使用萬惡的replace new
Tip: don’t use swap. Memory is cheap. Buy more!

● Fast containers

● Lambda functions

If only at runtime you know what the target is, you have no choice but to use std::function

If you know at compile time which target is to be run, then prefer lambdas template
void SendMessage(T&& target) {
 // populate and send message 
 target(mBuffer);
 send(mBuffer);
 } 

 SendMessage([&](auto& message) { 
 message.field1 = x; 
 ... message.field3 = z;
 });


Surprises and side notes:
Older versions of gcc’s implementation had copy on write semantics (新版比較快)

#include <string> #include <iostream> int main() { std::string a(50, 'c'); std::string b = a; *const_cast<char*>(a.c_str()) = 'A'; std::cout << "a: " << a << "\nb: " << b << std::endl; }

GCC < 5:
$ g++ -std=c++11 main.cpp && ./a.out
a: Accccccccccccccccccccccccccccccccccccccccccccccccc
b: Accccccccccccccccccccccccccccccccccccccccccccccccc
Aha! Copy-on-write in action.
GCC >= 5:
$ g++-5 -std=c++11 main.cpp && ./a.out
a: Accccccccccccccccccccccccccccccccccccccccccccccccc
b: cccccccccccccccccccccccccccccccccccccccccccccccccc
clang:

$ clang++ -std=c++11 -stdlib=libc++ main.cpp && ./a.out
a: Accccccccccccccccccccccccccccccccccccccccccccccccc
b: cccccccccccccccccccccccccccccccccccccccccccccccccc

reference: http://shaharmike.com/cpp/std-string/

沒有留言:

張貼留言