Skip to content

Instantly share code, notes, and snippets.

@sehe
Last active August 29, 2015 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sehe/54caed4b4cd7c9352174 to your computer and use it in GitHub Desktop.
Save sehe/54caed4b4cd7c9352174 to your computer and use it in GitHub Desktop.
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
ConstructorInitializerIndentWidth: 8
AlignEscapedNewlinesLeft: false
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AllowShortFunctionsOnASingleLine: true
AlwaysBreakTemplateDeclarations: false
AlwaysBreakBeforeMultilineStrings: false
BreakBeforeBinaryOperators: false
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BinPackParameters: true
ColumnLimit: 120
ConstructorInitializerAllOnOneLineOrOnePerLine: false
DerivePointerBinding: false
ExperimentalAutoDetectBinPacking: false
IndentCaseLabels: false
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyBreakFirstLessLess: 120
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerBindsToType: false
SpacesBeforeTrailingComments: 1
Cpp11BracedListStyle: false
Standard: Cpp03
IndentWidth: 4
TabWidth: 4
UseTab: Never
BreakBeforeBraces: Attach
IndentFunctionDeclarationAfterType: false
SpacesInParentheses: false
SpacesInAngles: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: true
SpaceBeforeAssignmentOperators: true
ContinuationIndentWidth: 4
CommentPragmas: '^ IWYU pragma:'
SpaceBeforeParens: ControlStatements
...
# This file is NOT licensed under the GPLv3, which is the license for the rest
# of YouCompleteMe.
#
# Here's the license text for this file:
#
# This is free and unencumbered software released into the public domain.
#
# Anyone is free to copy, modify, publish, use, compile, sell, or
# distribute this software, either in source code form or as a compiled
# binary, for any purpose, commercial or non-commercial, and by any
# means.
#
# In jurisdictions that recognize copyright laws, the author or authors
# of this software dedicate any and all copyright interest in the
# software to the public domain. We make this dedication for the benefit
# of the public at large and to the detriment of our heirs and
# successors. We intend this dedication to be an overt act of
# relinquishment in perpetuity of all present and future rights to this
# software under copyright law.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
# OTHER DEALINGS IN THE SOFTWARE.
#
# For more information, please refer to <http://unlicense.org/>
import os
import ycm_core
# These are the compilation flags that will be used in case there's no
# compilation database set (by default, one is not set).
# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
flags = [
'-Wall',
'-Wextra',
'-Wno-variadic-macros',
'-fexceptions',
'-DNDEBUG',
'-DUNIT_TESTS',
'-std=c++11',
'-x', 'c++',
'-isystem', '/home/sehe/custom/boost',
'-isystem', '/usr/lib/gcc/x86_64-linux-gnu/4.8/include',
'-I', 'src',
'-I', 'include',
'-I', '/home/sehe/custom/nonius/include',
'-isystem', '/usr/include',
'-isystem', '/usr/local/include',
]
# Set this to the absolute path to the folder (NOT the file!) containing the
# compile_commands.json file to use that instead of 'flags'. See here for
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
#
# Most projects will NOT need to set this to anything; you can just change the
# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
compilation_database_folder = ''
if os.path.exists( compilation_database_folder ):
database = ycm_core.CompilationDatabase( compilation_database_folder )
else:
database = None
SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm', '*.cs' ]
def DirectoryOfThisScript():
return os.path.dirname( os.path.abspath( __file__ ) )
def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
if not working_directory:
return list( flags )
new_flags = []
make_next_absolute = False
path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
for flag in flags:
new_flag = flag
if make_next_absolute:
make_next_absolute = False
if not flag.startswith( '/' ):
new_flag = os.path.join( working_directory, flag )
for path_flag in path_flags:
if flag == path_flag:
make_next_absolute = True
break
if flag.startswith( path_flag ):
path = flag[ len( path_flag ): ]
new_flag = path_flag + os.path.join( working_directory, path )
break
if new_flag:
new_flags.append( new_flag )
return new_flags
def IsHeaderFile( filename ):
extension = os.path.splitext( filename )[ 1 ]
return extension in [ '.h', '.hxx', '.hpp', '.hh' ]
def GetCompilationInfoForFile( filename ):
# The compilation_commands.json file generated by CMake does not have entries
# for header files. So we do our best by asking the db for flags for a
# corresponding source file, if any. If one exists, the flags for that file
# should be good enough.
if IsHeaderFile( filename ):
basename = os.path.splitext( filename )[ 0 ]
for extension in SOURCE_EXTENSIONS:
replacement_file = basename + extension
if os.path.exists( replacement_file ):
compilation_info = database.GetCompilationInfoForFile(
replacement_file )
if compilation_info.compiler_flags_:
return compilation_info
return None
return database.GetCompilationInfoForFile( filename )
def FlagsForFile( filename, **kwargs ):
if database:
# Bear in mind that compilation_info.compiler_flags_ does NOT return a
# python list, but a "list-like" StringVec object
compilation_info = GetCompilationInfoForFile( filename )
if not compilation_info:
return None
final_flags = MakeRelativePathsInFlagsAbsolute(
compilation_info.compiler_flags_,
compilation_info.compiler_working_dir_ )
# NOTE: This is just for YouCompleteMe; it's highly likely that your project
# does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR
# ycm_extra_conf IF YOU'RE NOT 100% SURE YOU NEED IT.
try:
final_flags.remove( '-stdlib=libc++' )
except ValueError:
pass
else:
relative_to = DirectoryOfThisScript()
final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to )
return {
'flags': final_flags,
'do_cache': True
}
#include <boost/thread/thread.hpp>
#include <boost/atomic.hpp>
#include <atomic>
#include <boost/lockfree/spsc_queue.hpp>
#include <string>
#include <cstdio>
#include <sched.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <boost/scoped_ptr.hpp>
#include <sys/time.h>
#include <boost/lexical_cast.hpp>
#include "optional_nonius.hpp"
void setThreadAffinity(boost::thread * const bt, int32_t const coreNumber){
cpu_set_t cst;
CPU_ZERO(&cst);
CPU_SET(coreNumber,&cst);
pthread_setaffinity_np(bt->native_handle(),sizeof(cst),&cst);
}
void setThreadAffinity(int32_t const coreNumber){
cpu_set_t cst;
CPU_ZERO(&cst);
CPU_SET(coreNumber,&cst);
sched_setaffinity(0,sizeof(cst),&cst);
}
struct Log{
public:
Log(std::string const & logFileName, int32_t coreNumber, int32_t queueSize)
: logFileName(logFileName), lock(ATOMIC_FLAG_INIT)
{
#ifdef NONIUS
fp = std::fopen(logFileName.c_str(), "w");
#else
fp = stderr; //std::fopen(logFileName.c_str(),"w")),
#endif
std::atomic_store_explicit(&this->flag,true,std::memory_order_release);
this->q.reset(new boost::lockfree::spsc_queue<std::string>(queueSize));
this->thrd.reset(new boost::thread(&Log::pop,this));
setThreadAffinity(this->thrd.get(),coreNumber);
}
void pop(){
// setThreadAffinity(this->coreNumber);
std::string s;
s.reserve(1000);
struct timeval ts;
while (std::atomic_load_explicit(&this->flag,std::memory_order_acquire)){
while (this->q->pop(s)){
gettimeofday(&ts,NULL);
std::fprintf(this->fp,"%li.%06li %s\n",ts.tv_sec,ts.tv_usec,s.c_str());
}
std::fflush(this->fp);
}
while (this->q->pop(s)){
gettimeofday(&ts,NULL);
std::fprintf(this->fp,"%li.%06li %s\n",ts.tv_sec,ts.tv_usec,s.c_str());
}
}
void push(std::string const & s){
while (std::atomic_flag_test_and_set_explicit(&this->lock,std::memory_order_acquire));
while (!this->q->push(s));
std::atomic_flag_clear_explicit(&this->lock,std::memory_order_release);
}
~Log(){
std::atomic_store_explicit(&this->flag,false,std::memory_order_release);
this->thrd->join();
std::fflush(this->fp);
std::fclose(this->fp);
this->fp = NULL;
}
private:
Log(){}
std::string logFileName;
boost::scoped_ptr<boost::lockfree::spsc_queue<std::string> > q;
boost::scoped_ptr<boost::thread> thrd;
std::atomic<bool> flag;
std::atomic_flag lock;
FILE * fp;
};
// this is the piece of code that achieves the best time -> about 2-3 microseconds for this single print on the server i use
NONIUS_BENCHMARK("direct-simple", [](nonius::chronometer meter) {
Log l("/dev/null",15,1024);
for (size_t i=0; i<10; ++i) l.push("warm up maybe");
meter.measure([&](int) {
std::string s("let's log this long line");
l.push(s);
});
})
#include <boost/thread/thread.hpp>
#include <boost/atomic.hpp>
#include <atomic>
#include <boost/lockfree/spsc_queue.hpp>
#include <string>
#include <cstdio>
#include <sched.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <boost/scoped_ptr.hpp>
#include <sys/time.h>
#include <boost/lexical_cast.hpp>
#include "optional_nonius.hpp"
void setThreadAffinity(boost::thread * const bt, int32_t const coreNumber){
cpu_set_t cst;
CPU_ZERO(&cst);
CPU_SET(coreNumber,&cst);
pthread_setaffinity_np(bt->native_handle(),sizeof(cst),&cst);
}
void setThreadAffinity(int32_t const coreNumber){
cpu_set_t cst;
CPU_ZERO(&cst);
CPU_SET(coreNumber,&cst);
sched_setaffinity(0,sizeof(cst),&cst);
}
struct Log{
public:
Log(std::string const & logFileName, int32_t coreNumber, int32_t queueSize)
: logFileName(logFileName), lock(ATOMIC_FLAG_INIT)
{
#ifdef NONIUS
fp = std::fopen(logFileName.c_str(), "w");
#else
fp = stderr; //std::fopen(logFileName.c_str(),"w")),
#endif
std::atomic_store_explicit(&this->flag,true,std::memory_order_release);
this->q.reset(new boost::lockfree::spsc_queue<std::string>(queueSize));
this->thrd.reset(new boost::thread(&Log::pop,this));
setThreadAffinity(this->thrd.get(),coreNumber);
}
void pop(){
// setThreadAffinity(this->coreNumber);
std::string s;
s.reserve(1000);
struct timeval ts;
while (std::atomic_load_explicit(&this->flag,std::memory_order_acquire)){
while (this->q->pop(s)){
gettimeofday(&ts,NULL);
std::fprintf(this->fp,"%li.%06li %s\n",ts.tv_sec,ts.tv_usec,s.c_str());
}
std::fflush(this->fp);
}
while (this->q->pop(s)){
gettimeofday(&ts,NULL);
std::fprintf(this->fp,"%li.%06li %s\n",ts.tv_sec,ts.tv_usec,s.c_str());
}
}
template <typename T>
inline __attribute__((always_inline)) std::string stringer(T const & t){
return boost::lexical_cast<std::string>(t);
}
template<typename T, typename ... Args>
inline __attribute__((always_inline))
std::string stringer(T const & t, Args const & ... args){
return stringer(t) + stringer(args...);
}
template<typename T, typename ... Args>
inline __attribute__((always_inline)) void enqueue(T const& t, Args const & ... args){
this->push(stringer(t, args...));
}
void push(std::string const & s){
while (std::atomic_flag_test_and_set_explicit(&this->lock,std::memory_order_acquire));
while (!this->q->push(s));
std::atomic_flag_clear_explicit(&this->lock,std::memory_order_release);
}
~Log(){
std::atomic_store_explicit(&this->flag,false,std::memory_order_release);
this->thrd->join();
std::fflush(this->fp);
std::fclose(this->fp);
this->fp = NULL;
}
private:
Log(){}
std::string logFileName;
boost::scoped_ptr<boost::lockfree::spsc_queue<std::string> > q;
boost::scoped_ptr<boost::thread> thrd;
std::atomic<bool> flag;
std::atomic_flag lock;
FILE * fp;
};
// this is the piece of code that achieves the best time -> about 2-3 microseconds for this single print on the server i use
NONIUS_BENCHMARK("direct-variadic", [](nonius::chronometer meter) {
std::string const a_s("let's log this long line");
double a_d(atan(1)*4);
const char* const a_l = "literal";
Log l("/dev/null",15,1024);
// warmup
for (size_t i=0; i<10; ++i) l.enqueue(a_s, a_d, i, a_l);
meter.measure([&](int i) {
switch (i%3) {
case 0: l.enqueue(a_s, a_d, i, a_l); break;
case 1: l.enqueue(a_s, a_l, a_d, i); break;
case 2: l.enqueue(a_d, i, a_l); break;
}
});
})
SHELL=/bin/bash
TARGETS+=mine-simple direct-simple service-simple
TARGETS+=mine-variadic service-variadic direct-variadic
# wip
TARGETS+=smart-lambda subnano
all: nonius test
nonius:$(patsubst %,build/nonius/%,$(TARGETS))
html:$(patsubst %,build/nonius/%.html,$(TARGETS))
test:$(patsubst %,build/test/%,$(TARGETS))
text:$(patsubst %,build/nonius/%.txt,$(TARGETS))
bench: html text
upload:bench
rsync build/nonius/*.{html,txt} *.cpp www-data@koolu:downloads/stackoverflow/q28254996/
rsync build/nonius/*.{html,txt} *.cpp www-data@linode:downloads/stackoverflow/q28254996/
CPPFLAGS+=-std=c++11 -Wall -pedantic
CPPFLAGS+=-g -O3
CPPFLAGS+=-isystem ~/custom/boost/
CPPFLAGS+=-I ~/custom/nonius/include
CPPFLAGS+=-pthread
CPPFLAGS+=-DNDEBUG
# CPPFLAGS+=-fopenmp
CPPFLAGS+=-march=native
LDFLAGS+=-L ~/custom/boost/stage/lib/ -Wl,-rpath,/home/sehe/custom/boost/stage/lib
LDFLAGS+=-lboost_system -lboost_thread -ltcmalloc
#LDFLAGS+=-lboost_system -lboost_regex -lboost_thread -lpthread -lboost_iostreams -lboost_serialization
#LDFLAGS+=-lboost_date_time
CXX=/usr/lib/gcc-snapshot/bin/g++
# CC=/usr/lib/gcc-snapshot/bin/gcc
# CXX=clang++
# CC=clang
%.S:%.cpp
$(CXX) $(CPPFLAGS) $^ -S -masm=intel -o - | egrep -v '\s*\.' | c++filt > $@
build/nonius/%:%.cpp
mkdir -pv $(@D)
$(CXX) -DNONIUS $(CPPFLAGS) $< -o $@ $(LDFLAGS)
build/test/%:%.cpp
mkdir -pv $(@D)
$(CXX) $(CPPFLAGS) $< -o $@ $(LDFLAGS)
%.txt:%
./$< -o $@
%.html:%
./$< -r html -o $@
*/*/*: optional_nonius.hpp
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/atomic.hpp>
#include <boost/lockfree/spsc_queue.hpp>
#include <boost/thread/thread.hpp>
#include "optional_nonius.hpp"
/*
* safe for use from a single thread only
*/
template <unsigned line_maxchars = 1000>
class Log {
public:
Log(std::string const &logFileName, int32_t queueSize)
:
#ifdef NONIUS
fp(std::fopen(logFileName.c_str(), "w")),
#else
fp(stderr), //std::fopen(logFileName.c_str(),"w")),
#endif
_shutdown(false),
_thread(&Log::pop, this),
_queue(queueSize)
{ }
void pop() {
std::string s;
s.reserve(line_maxchars);
struct timeval ts;
while (!_shutdown) {
while (_queue.pop(s)) {
gettimeofday(&ts, NULL);
std::fprintf(fp, "%li.%06li %s\n", ts.tv_sec, ts.tv_usec, s.c_str());
}
std::fflush(fp); // RECONSIDER HERE?
}
while (_queue.pop(s)) {
gettimeofday(&ts, NULL);
std::fprintf(fp, "%li.%06li %s\n", ts.tv_sec, ts.tv_usec, s.c_str());
}
}
void enqueue(std::string const& s) {
push(s);
}
void push(std::string const &s) {
while (!_queue.push(s));
}
~Log() {
_shutdown = true;
_thread.join();
assert(_queue.empty());
std::fflush(fp);
std::fclose(fp);
fp = NULL;
}
private:
FILE *fp;
boost::atomic_bool _shutdown;
boost::thread _thread;
boost::lockfree::spsc_queue<std::string> _queue;
};
#include <chrono>
#include <iostream>
NONIUS_BENCHMARK("mine-simple", [](nonius::chronometer meter) {
Log<> l("/dev/null", 1024);
for (size_t i=0; i<10; ++i) l.enqueue("warm up maybe");
meter.measure([&l](long i) {
std::string s("let's log this long line");
l.enqueue(s);
});
})
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/atomic.hpp>
#include <boost/lockfree/spsc_queue.hpp>
#include <boost/thread/thread.hpp>
#include "optional_nonius.hpp"
/*
* safe for use from a single thread only
*/
template <unsigned line_maxchars = 1000>
class Log {
public:
Log(std::string const &logFileName, int32_t queueSize)
:
#ifdef NONIUS
fp(std::fopen(logFileName.c_str(), "w")),
#else
fp(stderr), //std::fopen(logFileName.c_str(),"w")),
#endif
_shutdown(false),
_thread(&Log::pop, this),
_queue(queueSize)
{ }
void pop() {
std::string s;
s.reserve(line_maxchars);
struct timeval ts;
while (!_shutdown) {
while (_queue.pop(s)) {
gettimeofday(&ts, NULL);
std::fprintf(fp, "%li.%06li %s\n", ts.tv_sec, ts.tv_usec, s.c_str());
}
std::fflush(fp); // RECONSIDER HERE?
}
while (_queue.pop(s)) {
gettimeofday(&ts, NULL);
std::fprintf(fp, "%li.%06li %s\n", ts.tv_sec, ts.tv_usec, s.c_str());
}
}
template <typename S, typename T> void stringer(S& stream, T const &t) {
stream << t;
}
template <typename S, typename T, typename... Args>
void stringer(S& stream, T const &t, Args const &... args) {
stringer(stream, t);
stringer(stream, args...);
}
template <typename T, typename... Args> void enqueue(T &t, Args const&... args) {
thread_local char buffer[line_maxchars] = {};
thread_local boost::iostreams::array_sink as(buffer);
boost::iostreams::stream<boost::iostreams::array_sink> stream(as);
//stream.open(as);
stringer(stream, t, args...);
auto output = as.output_sequence();
push(std::string(output.first, output.second));
}
void push(std::string const &s) {
while (!_queue.push(s));
}
~Log() {
_shutdown = true;
_thread.join();
assert(_queue.empty());
std::fflush(fp);
std::fclose(fp);
fp = NULL;
}
private:
FILE *fp;
boost::atomic_bool _shutdown;
boost::thread _thread;
boost::lockfree::spsc_queue<std::string> _queue;
};
#include <chrono>
#include <iostream>
NONIUS_BENCHMARK("mine-variadic", [](nonius::chronometer meter) {
std::string const a_s("let's log this long line");
double a_d(atan(1)*4);
const char* const a_l = "literal";
Log<> l("/dev/null", 1024);
// warmup
for (size_t i=0; i<10; ++i) l.enqueue(a_s, a_d, i, a_l);
meter.measure([&](int i) {
switch (i%3) {
case 0: l.enqueue(a_s, a_d, i, a_l); break;
case 1: l.enqueue(a_s, a_l, a_d, i); break;
case 2: l.enqueue(a_d, i, a_l); break;
}
});
})
#pragma once
#ifdef NONIUS
#include <nonius/benchmark.h++>
#include <nonius/main.h++>
#else
#include <utility>
namespace nonius {
struct chronometer {
template <typename F> void measure(F&& f, decltype(f(0))* = nullptr) const { for (int i=0;i<10;++i) std::move(f)(i); }
template <typename F> void measure(F&& f, decltype(f())* = nullptr) const { for (int i=0;i<10;++i) std::move(f)(); }
};
}
#define NONIUS_BENCHMARK(name,lambda) \
int main() { \
auto fake_nonius_ll = lambda; \
fake_nonius_ll(nonius::chronometer {}); \
}
#endif
#include <boost/thread/thread.hpp>
#include <boost/atomic.hpp>
#include <atomic>
#include <boost/lockfree/spsc_queue.hpp>
#include <string>
#include <sstream>
#include <cstdio>
#include <sched.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <boost/scoped_ptr.hpp>
#include <sys/time.h>
#include <boost/lexical_cast.hpp>
#include <boost/asio.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/move/utility.hpp>
#include "optional_nonius.hpp"
void setThreadAffinity(boost::thread * const bt, int32_t const coreNumber){
cpu_set_t cst;
CPU_ZERO(&cst);
CPU_SET(coreNumber,&cst);
pthread_setaffinity_np(bt->native_handle(),sizeof(cst),&cst);
}
void setThreadAffinity(int32_t const coreNumber){
cpu_set_t cst;
CPU_ZERO(&cst);
CPU_SET(coreNumber,&cst);
sched_setaffinity(0,sizeof(cst),&cst);
}
// make sure size of pushCores vector is only 1
struct Log{
public:
Log(std::string const & logFileName, int32_t coreNumber, int32_t queueSize, std::vector<int32_t> const & pushCores)
: logFileName(logFileName), lock(ATOMIC_FLAG_INIT)
{
#ifdef NONIUS
fp = std::fopen(logFileName.c_str(), "w");
#else
fp = stderr; //std::fopen(logFileName.c_str(),"w")),
#endif
std::atomic_store_explicit(&this->flag,true,std::memory_order_release);
this->q.reset(new boost::lockfree::spsc_queue<std::string>(queueSize));
this->thrd.reset(new boost::thread(&Log::pop,this));
setThreadAffinity(this->thrd.get(),coreNumber);
//
this->io_service.reset(new boost::asio::io_service);
this->work.reset(new boost::asio::io_service::work(*this->io_service));
for (unsigned i = 0; i < pushCores.size(); ++i){
boost::thread * t_thread = this->thread_pool.create_thread(boost::bind(&boost::asio::io_service::run,this->io_service.get()));
setThreadAffinity(t_thread,pushCores[i]);
}
}
inline __attribute__((always_inline)) void pop(){
// setThreadAffinity(this->coreNumber);
std::string s;
s.reserve(1000);
struct timeval ts;
while (std::atomic_load_explicit(&this->flag,std::memory_order_acquire)){
while (this->q->pop(s)){
gettimeofday(&ts,NULL);
std::fprintf(this->fp,"%li.%06li %s\n",ts.tv_sec,ts.tv_usec,s.c_str());
}
std::fflush(this->fp);
}
while (this->q->pop(s)){
gettimeofday(&ts,NULL);
std::fprintf(this->fp,"%li.%06li %s\n",ts.tv_sec,ts.tv_usec,s.c_str());
}
}
template <typename T>
inline __attribute__((always_inline)) std::string stringer(T const & t){
return boost::lexical_cast<std::string>(t);
}
template<typename T, typename ... Args>
inline __attribute__((always_inline))
std::string stringer(T const & t, Args const & ... args){
return stringer(t) + stringer(args...);
}
template<typename T>
inline __attribute__((always_inline)) void enqueue(T t){
this->io_service->post(t);
}
inline __attribute__((always_inline)) void push(std::string const & s){
while (std::atomic_flag_test_and_set_explicit(&this->lock,std::memory_order_acquire));
while (!this->q->push(s));
std::atomic_flag_clear_explicit(&this->lock,std::memory_order_release);
}
~Log(){
work.reset();
this->thread_pool.join_all();
std::atomic_store_explicit(&this->flag,false,std::memory_order_release);
this->thrd->join();
std::fflush(this->fp);
std::fclose(this->fp);
this->fp = NULL;
}
private:
Log(){}
std::string logFileName;
boost::scoped_ptr<boost::lockfree::spsc_queue<std::string> > q;
boost::scoped_ptr<boost::thread> thrd;
std::atomic<bool> flag;
std::atomic_flag lock;
FILE * fp;
boost::scoped_ptr<boost::asio::io_service> io_service;
boost::scoped_ptr<boost::asio::io_service::work> work;
boost::thread_group thread_pool;
};
NONIUS_BENCHMARK("service-simple", [](nonius::chronometer meter) {
std::vector<int32_t> pushCores;
for (int i = 0; i < 1; ++i) {
pushCores.push_back(i);
}
// pushCores.push_back(16); pushCores.push_back(17), pushCores.push_back(18), pushCores.push_back(19);
Log l("/dev/null",1,1024,pushCores);
for (size_t i=0; i<10; ++i) l.enqueue(boost::bind(&Log::push,&l,"warm up maybe"));
meter.measure([&l](int i) {
l.enqueue(boost::bind(&Log::push,&l,"let's print out this line"));
});
})
#include <boost/thread/thread.hpp>
#include <boost/atomic.hpp>
#include <atomic>
#include <boost/lockfree/spsc_queue.hpp>
#include <string>
#include <sstream>
#include <cstdio>
#include <sched.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <boost/scoped_ptr.hpp>
#include <sys/time.h>
#include <boost/lexical_cast.hpp>
#include <boost/asio.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/move/utility.hpp>
#include "optional_nonius.hpp"
void setThreadAffinity(boost::thread * const bt, int32_t const coreNumber){
cpu_set_t cst;
CPU_ZERO(&cst);
CPU_SET(coreNumber,&cst);
pthread_setaffinity_np(bt->native_handle(),sizeof(cst),&cst);
}
void setThreadAffinity(int32_t const coreNumber){
cpu_set_t cst;
CPU_ZERO(&cst);
CPU_SET(coreNumber,&cst);
sched_setaffinity(0,sizeof(cst),&cst);
}
// make sure size of pushCores vector is only 1
struct Log{
public:
Log(std::string const & logFileName, int32_t coreNumber, int32_t queueSize, std::vector<int32_t> const & pushCores)
: logFileName(logFileName), lock(ATOMIC_FLAG_INIT)
{
#ifdef NONIUS
fp = std::fopen(logFileName.c_str(), "w");
#else
fp = stderr; //std::fopen(logFileName.c_str(),"w")),
#endif
std::atomic_store_explicit(&this->flag,true,std::memory_order_release);
this->q.reset(new boost::lockfree::spsc_queue<std::string>(queueSize));
this->thrd.reset(new boost::thread(&Log::pop,this));
setThreadAffinity(this->thrd.get(),coreNumber);
//
this->io_service.reset(new boost::asio::io_service);
this->work.reset(new boost::asio::io_service::work(*this->io_service));
for (unsigned i = 0; i < pushCores.size(); ++i){
boost::thread * t_thread = this->thread_pool.create_thread(boost::bind(&boost::asio::io_service::run,this->io_service.get()));
setThreadAffinity(t_thread,pushCores[i]);
}
}
inline __attribute__((always_inline)) void pop(){
// setThreadAffinity(this->coreNumber);
std::string s;
s.reserve(1000);
struct timeval ts;
while (std::atomic_load_explicit(&this->flag,std::memory_order_acquire)){
while (this->q->pop(s)){
gettimeofday(&ts,NULL);
std::fprintf(this->fp,"%li.%06li %s\n",ts.tv_sec,ts.tv_usec,s.c_str());
}
std::fflush(this->fp);
}
while (this->q->pop(s)){
gettimeofday(&ts,NULL);
std::fprintf(this->fp,"%li.%06li %s\n",ts.tv_sec,ts.tv_usec,s.c_str());
}
}
template <typename T>
inline __attribute__((always_inline)) std::string stringer(T const & t){
return boost::lexical_cast<std::string>(t);
}
template<typename T, typename ... Args>
inline __attribute__((always_inline))
std::string stringer(T const & t, Args const & ... args){
return stringer(t) + stringer(args...);
}
template<typename T, typename ... Args>
inline __attribute__((always_inline)) void enqueue(T const& t, Args const & ... args){
io_service->post([&]{ this->push(stringer(t, args...)); });
}
inline __attribute__((always_inline)) void push(std::string const & s){
while (std::atomic_flag_test_and_set_explicit(&this->lock,std::memory_order_acquire));
while (!this->q->push(s));
std::atomic_flag_clear_explicit(&this->lock,std::memory_order_release);
}
~Log(){
work.reset();
this->thread_pool.join_all();
std::atomic_store_explicit(&this->flag,false,std::memory_order_release);
this->thrd->join();
std::fflush(this->fp);
std::fclose(this->fp);
this->fp = NULL;
}
private:
Log(){}
std::string logFileName;
boost::scoped_ptr<boost::lockfree::spsc_queue<std::string> > q;
boost::scoped_ptr<boost::thread> thrd;
std::atomic<bool> flag;
std::atomic_flag lock;
FILE * fp;
boost::scoped_ptr<boost::asio::io_service> io_service;
boost::scoped_ptr<boost::asio::io_service::work> work;
boost::thread_group thread_pool;
};
NONIUS_BENCHMARK("service-variadic", [](nonius::chronometer meter) {
std::string const a_s("let's log this long line");
double a_d(atan(1)*4);
const char* const a_l = "literal";
Log l("/dev/null",15,1024, {0});
// warmup
for (size_t i=0; i<10; ++i) l.enqueue(a_s, a_d, i, a_l);
meter.measure([&](int i) {
switch (i%3) {
case 0: l.enqueue(a_s, a_d, i, a_l); break;
case 1: l.enqueue(a_s, a_l, a_d, i); break;
case 2: l.enqueue(a_d, i, a_l); break;
}
});
})
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/function.hpp>
#include <boost/atomic.hpp>
#include <boost/lockfree/spsc_queue.hpp>
#include <boost/thread/thread.hpp>
#include "optional_nonius.hpp"
/*
* safe for use from a single thread only
*/
template <unsigned line_maxchars = 1000>
class Log {
public:
typedef boost::function<void(std::ostream&)> render_f;
Log(std::string const &logFileName, int32_t queueSize)
:
#ifdef NONIUS
fp(std::fopen(logFileName.c_str(), "w")),
#else
fp(stderr), //std::fopen(logFileName.c_str(),"w")),
#endif
_shutdown(false),
_thread(&Log::pop, this),
_queue(queueSize)
{ }
void pop() {
render_f f;
char buffer[line_maxchars+1] = {};
auto loop = [&] {
bool needflush = false;
while (_queue.pop(f)) {
needflush = true;
struct timeval ts;
gettimeofday(&ts, NULL);
boost::iostreams::array_sink as(buffer, line_maxchars);
boost::iostreams::stream<boost::iostreams::array_sink> stream(as);
f(stream);
stream.rdbuf()->sputc('\0');
std::fprintf(fp, "%li.%06li %s\n", ts.tv_sec, ts.tv_usec, buffer);
}
return needflush;
};
while (!_shutdown) {
if (loop())
std::fflush(fp);
}
if (loop())
std::fflush(fp);
}
void push(render_f f) {
while (!_queue.push(f));
}
~Log() {
_shutdown = true;
_thread.join();
assert(_queue.empty());
std::fflush(fp);
std::fclose(fp);
fp = NULL;
}
private:
FILE *fp;
boost::atomic_bool _shutdown;
boost::thread _thread;
boost::lockfree::spsc_queue<render_f> _queue;
};
#include <chrono>
#include <iostream>
#define LOG(body) do { l.push([=](std::ostream& os) { body; }); } while(false);
NONIUS_BENCHMARK("mine-smart-variadic", [](nonius::chronometer meter) {
std::string const a_s("let's log this long line");
double a_d(atan(1)*4);
const char* const a_l = "literal";
Log<> l("/dev/null", 1024);
// warmup
for (size_t i=0; i<10; ++i) l.push([&](std::ostream& os) { os << a_s << a_d << i << a_l; });
meter.measure([&](int i) {
switch (i%3) {
case 0: LOG(os << a_s << a_d << i << a_l); break;
case 1: LOG(os << a_s << a_l << a_d << i); break;
case 2: LOG(os << a_d << i << a_l); break;
}
});
})
#define _BLITZ_LOGGER_H_
#include <boost/thread/thread.hpp>
#include <boost/atomic.hpp>
#include <atomic>
#include <boost/lockfree/spsc_queue.hpp>
#include <string>
#include <sstream>
#include <cstdio>
#include <sched.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <boost/scoped_ptr.hpp>
#include <sys/time.h>
#include <boost/lexical_cast.hpp>
#include <boost/asio.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/move/utility.hpp>
#include <functional>
#include <tr1/functional>
#include "optional_nonius.hpp"
void setThreadAffinity(boost::thread * const bt, int32_t const coreNumber){
cpu_set_t cst;
CPU_ZERO(&cst);
CPU_SET(coreNumber,&cst);
pthread_setaffinity_np(bt->native_handle(),sizeof(cst),&cst);
}
void setThreadAffinity(int32_t const coreNumber){
cpu_set_t cst;
CPU_ZERO(&cst);
CPU_SET(coreNumber,&cst);
sched_setaffinity(0,sizeof(cst),&cst);
}
namespace blitz {
template <unsigned popResSize = 1024> struct BlitzLogger {
public:
BlitzLogger(std::string const &logFileName, int32_t const popCore, int32_t const pushCore, int32_t queueSize)
:
#ifdef NONIUS
fp(std::fopen(logFileName.c_str(), "w")),
#else
fp(stderr), //std::fopen(logFileName.c_str(),"w")),
#endif
flag(true),
_queue(queueSize),
pop_thread(&BlitzLogger::pop, this),
io_service(),
work(boost::asio::io_service::work(io_service)),
push_thread(boost::bind(&boost::asio::io_service::run, &io_service))
{
setThreadAffinity(&pop_thread, popCore);
setThreadAffinity(&push_thread, pushCore);
}
template <typename... Args> void enqueue(Args const &... args) { concatenate(args...); }
~BlitzLogger() {
work.reset();
push_thread.join();
flag = false;
pop_thread.join();
std::fflush(fp);
if (fp != stdout && fp != stderr)
std::fclose(fp);
fp = NULL;
}
private:
FILE *fp;
std::atomic<bool> flag;
boost::lockfree::spsc_queue<std::string> _queue;
boost::thread pop_thread;
boost::asio::io_service io_service;
boost::optional<boost::asio::io_service::work> work;
boost::thread push_thread;
void pop() {
std::string s;
s.reserve(popResSize);
struct timeval ts;
while (flag) {
while (_queue.pop(s)) {
gettimeofday(&ts, NULL);
std::fprintf(fp, "%li.%06li %s\n", ts.tv_sec, ts.tv_usec, s.c_str());
}
std::fflush(fp);
}
while (_queue.pop(s)) {
gettimeofday(&ts, NULL);
std::fprintf(fp, "%li.%06li %s\n", ts.tv_sec, ts.tv_usec, s.c_str());
}
}
template <typename T> std::string stringer(T const &t) {
return boost::lexical_cast<std::string>(t);
}
template <typename T, typename... Args>
std::string stringer(T const &t, Args const &... args) {
return stringer(t) + stringer(args...);
}
template <typename... Args> void concatenate(Args const&... args) {
io_service.post(
std::tr1::bind(&BlitzLogger::push, this,
std::tr1::bind(&BlitzLogger::stringer<Args const &...>, this, args...)));
}
void push(std::string const &s) {
while (!_queue.push(s));
}
};
}
#include <chrono>
#include <iostream>
#define LOG(body) do { l.push([=](std::ostream& os) { body; }); } while(false);
NONIUS_BENCHMARK("subnano", [](nonius::chronometer meter) {
std::string const a_s("let's log this long line");
double a_d(atan(1)*4);
const char* const a_l = "literal";
blitz::BlitzLogger<> l("/dev/null",15,15,1024);
// warmup
for (size_t i=0; i<10; ++i) l.enqueue(a_s, a_d, i, a_l);
meter.measure([&](int i) {
switch (i%3) {
case 0: l.enqueue(a_s, a_d, i, a_l); break;
case 1: l.enqueue(a_s, a_l, a_d, i); break;
case 2: l.enqueue(a_d, i, a_l); break;
}
});
})
#if 0
int main(){
BlitzLogger<> l("/tmp/junk.log",15,15,1024);
struct timeval ts_1, ts_2;
gettimeofday(&ts_1,NULL);
// burn in
for (int64_t i = 0; i < 10; ++i){
l.enqueue("hello",1,2,3,5.36," world\n");
}
gettimeofday(&ts_1,NULL);
{
for (int i = 0; i < 333333; ++i){
// l.enqueue("hello",42,32,45);
l.enqueue("check this out", 2, 4.3, "junk it\n");
l.enqueue("trade @ ", 100," for ", 42000,"sadadahares for instrument ", 4.3, "junk it\n",42);
l.enqueue("check thasdadis out", 2, 4.3, "junasdk it","trade @ ", 100," for ", 42000,
"check adadathasdadis out", 2, 4.3, "juadadadnasdk it","tradeasd @ ", 100," for ", 420930,
"check thasdadis out", 2, 4.3, "junasdk it","trade @ ", 100," for ", 42000);
}
}
gettimeofday(&ts_2,NULL);
std::fprintf(stderr,"%li microsec\n",(ts_2.tv_sec-ts_1.tv_sec)*1000000+(ts_2.tv_usec-ts_1.tv_usec));
#endif
simple: /home/sehe/custom/boost/boost/smart_ptr/scoped_ptr.hpp:99: T* boost::scoped_ptr<T>::operator->() const [with T = boost::lockfree::spsc_queue<std::basic_string<char> >]: Assertion `px != 0' failed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment