理系学生日記

おまえはいつまで学生気分なのか

問題3-40 (3.4.1 The Nature of Time in Concurrent Systems)

この場合,x の値としてはどのような可能性があるのか.

(define x 10)

(parallel-execute (lambda () (set! x (* x x)))
                  (lambda () (set! x (* x x x))))

乗算が atomic と仮定してのことだけど,x の読み出しと,計算と,代入の間それぞれに,インタリーブの危険がある.
(lambda () (set! x (* x x))) を pA,(lambda () (set! x (* x x x))) を pB と呼ぶことにし,さらにそれぞれの x の読み出し部分をr_{1,2,3}{A,B},計算部分をm_{A,B},代入部分をa_{A,B} と呼ぶことにする.
そうすると,最終的な x の値としては以下のパターンが考えられる.

  1. 例: (r_1A,r_2A,m_A,a_A,r_1B,r_2B,r_3B,m_B,a_B) : (10^2)^3=1,000,000
  2. 例: (r_1A,r_2A,m_A,r_1B,r_2B,r_3B,m_B,a_A,a_B) : (10^3)=1,000
  3. 例: (r_1A,r_2A,m_A,r_1B,r_2B,r_3B,m_B,a_B,a_A) : (10^2)=100
  4. 例: (r_1A,r_1B,r_2B,r_3B,m_B,a_B,r_2A,m_A,a_A) : 10x10^3=10,000
  5. 例: (r_1B,r_1A,r_2A,m_A,a_A,r_2B,r_3B,m_B,a_B) : 10x10^2x10^2=100,000
  6. 例: (r_1B,r_2B,r_1A,r_2A,m_A,a_A,r_3B,m_B,a_B) : 10x10x10^2=10,000

では,parallel-execute に渡す関数を両方とも直列化した場合

(define x 10)

(define s (make-serializer))

(parallel-execute (s (lambda () (set! x (* x x))))
                  (s (lambda () (set! x (* x x x)))))

このときの最終的な x の結果としては,1,000,000 のみとなる.