Lecture 13

SFR1811·2022년 2월 5일
0

CS343-Parallel Programming

목록 보기
10/24

5.18.8 N-Thread Prioritized Entry

_Task Worker {
  Intent * intents;
  int N, priority, i, j;
  void main() {
    for ( i = 1; i <= 1000; i += 1 ) {
    // step 1, wait for threads with higher priority
      do { // entry protocol
        intents[priority] = WantIn;
        // check if thread with higher priority wants in
        for ( j = priority - 1; j >= 0; j -= 1 ) {
          if ( intents[j] == WantIn ) {
            intents[priority] = DontWantIn;
            while ( intents[j] == WantIn ) {}
            break;
          } // exit
        }
      } while ( intents[priority] == DontWantIn );
      // step 2, wait for threads with lower priority
      for ( j = priority + 1; j < N; j += 1 ) {
          while ( intents[j] == WantIn ) {}
      }
      CriticalSection(); // critical section
      intents[priority] = DontWantIn; // exit protocol
    }
  }
 public:
  Worker( Intent intents[ ], int N, int priority ) :
  intents( intents ), N(N), priority( priority ) {}
};
int main() {
  const int NoOfTasks = 10;
  Intent intents[NoOfTasks]; // shared
  Worker *workers[NoOfTasks];
  for ( int i = 0; i < NoOfTasks; i += 1 ) { // initialize shared data
  	intents[i] = DontWantIn;
  }
  for ( int i = 0; i < NoOfTasks; i += 1 ) {
  	workers[i] = new Worker( intents, NoOfTasks, i ); // create workers
  }
  for ( int i = 0; i < NoOfTasks; i += 1 ) { // terminate workers
  	delete workers[i];
  }
}

thread with n priority will first scan higher priority boards for any intent/usage of CS,
then looks for intent/usage of lower priorities.


5.18.9 Bakery (Ticket)

  1. there are n array of waiting spots (that is for each thread)
  2. if thread want to hold lock, it assign its position in waiting spot to be '0',
  3. search for highest ticket num from WS then add 1 then assign it to its own WS
  4. scan from 0 ~ n.
    • if WS[i] > WS[self] : move on
    • if WS[i] < WS[self] : wait until its gone
    • else : if i > self, wait. else , move on

5.18.10 Tournament

for N threads, make N/2 pairs and put them all under Dekker's algorithm in reversed tree path.


5.18.11 Arbiter

create a full-time arbitrator task to control entry to CS.

There is an Arbiter that looks for intents, and chooses a intent to enter CS.

This is not mutual exclusion!
This is syncronization!

Difference
mutual exclusion is not allowing two threads to enter CS at the same time.
syncronization is setting order for threads. more costly.


5.19 Hardware solutions to mutual exclusion

Cheat in order and speed of execution!
It simplifies the problem.

make a special instructions to perform an atomic read+write operation

int Lock = OPEN //shared
int TestSet(int &b){
  //begin atomic
  int temp = b;
  b = CLOSED;
  // end atomic
  return temp;
}
void Task::main(){
  while(TestSet(Lock) == CLOSED);
  // CS
  Lock = OPEN;
}

This only works for a single CPU.
To make this work, hardware needs to be implemented so that if Lock is locked, it actually blocks(stall) other CPU.


5.19.2 Swap Instruction

Atomic swap

int Lock = OPEN
void Swap(int &a, &b){
  int temp;
  // begin atomic
  temp = a;
  a = b;
  b = temp;
  // end atomic
}
void Task::main(){
  int dummy = CLOSED;
  do{
    Swap(Lock, dummy);
  }while(dummy == CLOSED);
  // CS
  Lock = open
}

it does not a read and a write atomically, it does two reads and two writes atomically.


6 Locks

Spin lock busy waits burning massive amount of CPU time.
What we want to do is to do is to go sleep while waiting.

6.2.1 Lock implementation

uLock{
  void acquire();
  void release();
}

uLock lock(/* 0 - locked, 1 - opened */)
profile
3B CS

0개의 댓글