Module 11: "Synchronization"
  Lecture 23: "Barriers and Speculative Synchronization"
 

Barrier

  • High-level classification of barriers
    • Hardware and software barriers
  • Will focus on two types of software barriers
    • .Centralized barrier: every processor polls a single count
    • Distributed tree barrier: shows much better scalability
  • Performance goals of a barrier implementation
    • Low latency: after all processors have arrived at the barrier, they should be able to leave quickly
    • Low traffic: minimize bus transaction and contention
    • Scalability: latency and traffic should scale slowly with the number of processors
    • Low storage: barrier state should not be big
    • Fairness: Preserve some strict order of barrier exit (could be FIFO according to arrival order); a particular processor should not always be the last one to exit

Centralized barrier

struct bar_type {
   int counter;
   struct lock_type lock;
   int flag = 0;
} bar_name;

BARINIT (bar_name) {
   LOCKINIT(bar_name.lock);
   bar_name.counter = 0;
}

BARRIER (bar_name, P) {
   int my_count;
   LOCK (bar_name.lock);
   if (!bar_name.counter) {
      bar_name.flag = 0; /* first one */
   }
   my_count = ++bar_name.counter;
   UNLOCK (bar_name.lock);
   if (my_count == P) {
      bar_name.counter = 0;
      bar_name.flag = 1; /* last one */
   }
   else {
       while (!bar_name.flag);
   }
}

Sense reversal

  • The last implementation fails to work for two consecutive barrier invocations
    • Need to prevent a process from entering a barrier instance until all have left the previous instance
    • Reverse the sense of a barrier i.e. every other barrier will have the same sense: basically attach parity or sense to a barrier

      BARRIER (bar_name, P) {
         local sense = !local_sense; /* this is private per processor */
         LOCK (bar_name.lock);
         bar_name.counter++;
         if (bar_name.counter == P) {
            UNLOCK (bar_name.lock);
            bar_name.counter = 0;
            bar_name.flag = local_sense;
         }
         else {
             UNLOCK (bar_name.lock);
             while (bar_name.flag != local_sense);
         }
      }