diff options
-rw-r--r-- | include/gras/gras.hpp | 9 | ||||
-rw-r--r-- | lib/block_task.cpp | 12 | ||||
-rw-r--r-- | lib/gras_impl/debug.hpp | 2 | ||||
-rw-r--r-- | lib/tag_handlers.hpp | 4 | ||||
-rw-r--r-- | lib/theron_allocator.cpp | 6 |
5 files changed, 21 insertions, 12 deletions
diff --git a/include/gras/gras.hpp b/include/gras/gras.hpp index 748e682..6d1808b 100644 --- a/include/gras/gras.hpp +++ b/include/gras/gras.hpp @@ -57,6 +57,15 @@ #define GRAS_FORCE_INLINE inline #endif +//want to have fun with branch prediction hints? +#ifdef __GNUC__ + #define GRAS_LIKELY(expr) (__builtin_expect(bool(expr), 1)) + #define GRAS_UNLIKELY(expr) (__builtin_expect(bool(expr), 0)) +#else + #define GRAS_LIKELY(expr) (expr) + #define GRAS_UNLIKELY(expr) (expr) +#endif + namespace gras { //! Typedef for absolute item indexes diff --git a/lib/block_task.cpp b/lib/block_task.cpp index af8f101..47c0019 100644 --- a/lib/block_task.cpp +++ b/lib/block_task.cpp @@ -104,7 +104,7 @@ void BlockActor::handle_task(void) //-- however, not all ports may have available buffers. //------------------------------------------------------------------ this->handle_task_count++; - if (not this->is_work_allowed()) return; + if GRAS_UNLIKELY(not this->is_work_allowed()) return; this->work_count++; #ifdef WORK_DEBUG @@ -115,7 +115,7 @@ void BlockActor::handle_task(void) //-- Asynchronous notification through atomic variable //-- that the executor has instructed workers to stop. //------------------------------------------------------------------ - if (active_token.expired()) + if GRAS_UNLIKELY(active_token.expired()) { this->mark_done(); return; @@ -146,7 +146,7 @@ void BlockActor::handle_task(void) //inline dealings, how and when input buffers can be inlined into output buffers //* - if ( + if GRAS_UNLIKELY( buff.unique() and input_configs[i].inline_buffer and output_inline_index < num_outputs and @@ -185,7 +185,7 @@ void BlockActor::handle_task(void) //------------------------------------------------------------------ //-- the work //------------------------------------------------------------------ - if (this->interruptible_thread) + if GRAS_UNLIKELY(this->interruptible_thread) { this->interruptible_thread->call(); } @@ -211,7 +211,7 @@ void BlockActor::handle_task(void) { const bool nothing = this->input_queues.empty(i) and this->input_tags[i].empty(); this->inputs_available.set(i, not nothing); - if (this->is_input_done(i)) this->mark_done(); + if GRAS_UNLIKELY(this->is_input_done(i)) this->mark_done(); } //still have IO ready? kick off another task @@ -252,7 +252,7 @@ void BlockActor::produce_buffer(const size_t i, const SBuffer &buffer) GRAS_FORCE_INLINE void BlockActor::flush_output(const size_t i) { - if (this->output_queues.empty(i) or this->output_queues.front(i).length == 0) return; + if GRAS_UNLIKELY(this->output_queues.empty(i) or this->output_queues.front(i).length == 0) return; SBuffer &buff = this->output_queues.front(i); InputBufferMessage buff_msg; buff_msg.buffer = buff; diff --git a/lib/gras_impl/debug.hpp b/lib/gras_impl/debug.hpp index 7ec71e0..61376d5 100644 --- a/lib/gras_impl/debug.hpp +++ b/lib/gras_impl/debug.hpp @@ -59,7 +59,7 @@ extern void *operator new(std::size_t n) throw (std::bad_alloc); //-- implementation for assert debug //---------------------------------------------------------------------- #ifdef ASSERTING -#define ASSERT(x) {if(not (x)) \ +#define ASSERT(x) {if GRAS_UNLIKELY(not (x)) \ { \ std::cerr << "ASSERT FAIL " << __FILE__ << ":" << __LINE__ << "\n\t" << #x << std::endl << std::flush; \ throw std::runtime_error(std::string("ASSERT FAIL ") + #x); \ diff --git a/lib/tag_handlers.hpp b/lib/tag_handlers.hpp index 4e018b6..e2eb3b9 100644 --- a/lib/tag_handlers.hpp +++ b/lib/tag_handlers.hpp @@ -11,7 +11,7 @@ namespace gras GRAS_FORCE_INLINE void BlockActor::sort_tags(const size_t i) { - if (not this->input_tags_changed[i]) return; + if GRAS_LIKELY(not this->input_tags_changed[i]) return; std::vector<Tag> &tags_i = this->input_tags[i]; std::sort(tags_i.begin(), tags_i.end()); this->input_tags_changed[i] = false; @@ -32,7 +32,7 @@ GRAS_FORCE_INLINE void BlockActor::trim_tags(const size_t i) last++; } - if (last == 0) return; + if GRAS_LIKELY(last == 0) return; //call the overloaded propagate_tags to do the dirty work this->block_ptr->propagate_tags(i, TagIter(tags_i.begin(), tags_i.begin()+last)); diff --git a/lib/theron_allocator.cpp b/lib/theron_allocator.cpp index 8a654f3..9db9367 100644 --- a/lib/theron_allocator.cpp +++ b/lib/theron_allocator.cpp @@ -54,10 +54,10 @@ static struct WorkerAllocator : Theron::IAllocator void *Allocate(const SizeType size) { - if (size <= MY_ALLOCATOR_CHUNK_SIZE) + if GRAS_LIKELY(size <= MY_ALLOCATOR_CHUNK_SIZE) { mSpinLock.Lock(); - if (queue.empty()) + if GRAS_UNLIKELY(queue.empty()) { unwanted_malloc_count++; mSpinLock.Unlock(); @@ -78,7 +78,7 @@ static struct WorkerAllocator : Theron::IAllocator void Free(void *const memory) { const bool in_pool = ptrdiff_t(memory) >= ptrdiff_t(pool) and ptrdiff_t(memory) < pool_end; - if (in_pool) + if GRAS_LIKELY(in_pool) { mSpinLock.Lock(); queue.push_front(memory); |