diff --git a/miniapp/miniapp.cpp b/miniapp/miniapp.cpp
index fec0e995d56903f50a6b743b63df9eb01e428011..3867f4e8365fa8ac65bbe235e2e7fe915b94e60b 100644
--- a/miniapp/miniapp.cpp
+++ b/miniapp/miniapp.cpp
@@ -43,29 +43,29 @@ struct model {
             mc::threading::parallel_for::apply(
                 0, num_groups(),
                 [&](int i) {
-                        mc::util::profiler_enter("stepping","events");
+                    PE("stepping","events");
                     cell_groups[i].enqueue_events(communicator.queue(i));
-                        mc::util::profiler_leave();
+                    PL();
 
                     cell_groups[i].advance(std::min(t+delta, tfinal), dt);
 
-                        mc::util::profiler_enter("events");
+                    PE("events");
                     communicator.add_spikes(cell_groups[i].spikes());
                     cell_groups[i].clear_spikes();
-                        mc::util::profiler_leave(2);
+                    PL(2);
                 }
             );
 
-                mc::util::profiler_enter("stepping", "exchange");
+            PE("stepping", "exchange");
             communicator.exchange();
-                mc::util::profiler_leave(2);
+            PL(2);
 
             t += delta;
         }
     }
 
     void init_communicator() {
-            mc::util::profiler_enter("setup", "communicator");
+        PE("setup", "communicator");
 
         // calculate the source and synapse distribution serially
         std::vector<id_type> target_counts(num_groups());
@@ -81,11 +81,11 @@ struct model {
         //  create connections
         communicator = communicator_type(num_groups(), target_counts);
 
-            mc::util::profiler_leave(2);
+        PL(2);
     }
 
     void update_gids() {
-            mc::util::profiler_enter("setup", "globalize");
+        PE("setup", "globalize");
         auto com_policy = communicator.communication_policy();
         auto global_source_map = com_policy.make_map(source_map.back());
         auto domain_idx = communicator.domain_id();
@@ -97,7 +97,7 @@ struct model {
                 target_map[i]+communicator.target_gid_from_group_lid(0)
             );
         }
-            mc::util::profiler_leave(2);
+        PL(2);
     }
 
     // TODO : only stored here because init_communicator() and update_gids() are split
@@ -296,9 +296,9 @@ void all_to_all_model(nest::mc::io::cl_options& options, model& m) {
     mc::threading::parallel_for::apply(
         0, ncell_local,
         [&](int i) {
-                mc::util::profiler_enter("setup", "cells");
+            PE("setup", "cells");
             m.cell_groups[i] = make_lowered_cell(i, basic_cell);
-                mc::util::profiler_leave(2);
+            PL(2);
         }
     );
 
@@ -307,7 +307,7 @@ void all_to_all_model(nest::mc::io::cl_options& options, model& m) {
     //
     m.init_communicator();
 
-        mc::util::profiler_enter("setup", "connections");
+    PE("setup", "connections");
 
     // RNG distributions for connection delays and source cell ids
     auto weight_distribution = std::exponential_distribution<float>(0.75);
@@ -351,8 +351,7 @@ void all_to_all_model(nest::mc::io::cl_options& options, model& m) {
     //  setup probes
     //
 
-    mc::util::profiler_leave();
-    mc::util::profiler_enter("probes");
+    PL(); PE("probes");
 
     // monitor soma and dendrite on a few cells
     float sample_dt = 0.1;
@@ -378,7 +377,7 @@ void all_to_all_model(nest::mc::io::cl_options& options, model& m) {
         );
     }
 
-        mc::util::profiler_leave(2);
+    PL(2);
 }
 
 ///////////////////////////////////////
diff --git a/src/cell_group.hpp b/src/cell_group.hpp
index ff146bd1110eb873d5d83c35969b981a48579b5f..a5a6690cf08fe03f64f52d56a3577b0b0c747a52 100644
--- a/src/cell_group.hpp
+++ b/src/cell_group.hpp
@@ -81,7 +81,7 @@ public:
             // take any pending samples
             float cell_time = cell_.time();
 
-                nest::mc::util::profiler_enter("sampling");
+            PE("sampling");
             while (auto m = sample_events_.pop_if_before(cell_time)) {
                 auto& sampler = samplers_[m->sampler_index];
                 EXPECTS((bool)sampler.sample);
@@ -93,7 +93,7 @@ public:
                     sample_events_.push(*m);
                 }
             }
-                nest::mc::util::profiler_leave();
+            PL();
 
             // look for events in the next time step
             auto tstep = std::min(tfinal, cell_.time()+dt);
@@ -106,7 +106,7 @@ public:
                 std::cerr << "warning: solution out of bounds\n";
             }
 
-                nest::mc::util::profiler_enter("events");
+            PE("events");
             // check for new spikes
             for (auto& s : spike_sources_) {
                 if (auto spike = s.source.test(cell_, cell_.time())) {
@@ -124,7 +124,7 @@ public:
                     cell_.apply_event(e.get());
                 }
             }
-                nest::mc::util::profiler_leave();
+            PL();
         }
 
     }
diff --git a/src/fvm_cell.hpp b/src/fvm_cell.hpp
index 2fa86fd9d6326b3ffc1692f7c08c0fde00edf163..148f8ac55be791e2efaefd70e444dfef3a458058 100644
--- a/src/fvm_cell.hpp
+++ b/src/fvm_cell.hpp
@@ -513,15 +513,15 @@ void fvm_cell<T, I>::advance(T dt)
 {
     using memory::all;
 
-        mc::util::profiler_enter("current");
+    PE("current");
     current_(all) = 0.;
 
     // update currents from ion channels
     for(auto& m : mechanisms_) {
-            mc::util::profiler_enter(m->name().c_str());
+        PE(m->name().c_str());
         m->set_params(t_, dt);
         m->nrn_current();
-            mc::util::profiler_leave();
+        PL();
     }
 
     // add current contributions from stimulii
@@ -532,25 +532,25 @@ void fvm_cell<T, I>::advance(T dt)
         // the factor of 100 scales the injected current to 10^2.nA
         current_[loc] -= 100.*ie/cv_areas_[loc];
     }
-        mc::util::profiler_leave();
+    PL();
 
-        mc::util::profiler_enter("matrix", "setup");
+    PE("matrix", "setup");
     // solve the linear system
     setup_matrix(dt);
-        mc::util::profiler_leave(); mc::util::profiler_enter("solve");
+    PL(); PE("solve");
     matrix_.solve();
-        mc::util::profiler_leave();
+    PL();
     voltage_(all) = matrix_.rhs();
-        mc::util::profiler_leave();
+    PL();
 
-        mc::util::profiler_enter("state");
+    PE("state");
     // integrate state of gating variables etc.
     for(auto& m : mechanisms_) {
-            mc::util::profiler_enter(m->name().c_str());
+        PE(m->name().c_str());
         m->nrn_state();
-            mc::util::profiler_leave();
+        PL();
     }
-        mc::util::profiler_leave();
+    PL();
 
     t_ += dt;
 }
diff --git a/src/profiling/profiler.hpp b/src/profiling/profiler.hpp
index 7230697baab21f914fa3b92f4ffbed4382b062b6..4332925a5b3ee46c8c07164a80c4acf5abd72989 100644
--- a/src/profiling/profiler.hpp
+++ b/src/profiling/profiler.hpp
@@ -226,6 +226,7 @@ void profiler_enter(const char* n, Args... args) {
 
 /// move up one level in the profiler
 void profiler_leave();
+
 /// move up multiple profiler levels in one call
 void profiler_leave(int nlevels);
 
@@ -238,3 +239,8 @@ void profiler_output(double threshold);
 } // namespace util
 } // namespace mc
 } // namespace nest
+
+// define some helper macros to make instrumentation of the source code with calls
+// to the profiler a little less visually distracting
+#define PE nest::mc::util::profiler_enter
+#define PL nest::mc::util::profiler_leave