170 likes | 271 Views
Simpler Reasoning about Variables in Multithreaded Programs. Laura Effinger-Dean , Hans Boehm, Dhruva Chakrabarti , and Pramod Joisha University of Washington , HP Labs Dagstuhl : Multi-Core Memory Models and Concurrency Theory January 3-7, 2011. Assume data-race-freedom.
E N D
Simpler Reasoning about Variables in Multithreaded Programs Laura Effinger-Dean, Hans Boehm, DhruvaChakrabarti, and PramodJoisha University of Washington, HP Labs Dagstuhl: Multi-Core Memory Models and Concurrency Theory January 3-7, 2011
Assume data-race-freedom. Can another thread modify mtx_shared between A and B? Example A: tmp1 = mtx_shared; lock(tmp1); … // no synchronization B: tmp2 = mtx_shared; unlock(tmp2);
Overview • Reasoning about multithreaded, shared-memory code • Assume data-race-freedom • Data races ordered by happens-before • As in the new C/C++ language specifications • No knowledge of other threads’ activity • Status quo: optimization only within synchronization-free regions • We provide limited sequential reasoning for blocks of code that include some synchronization • Simple analysis, but can be generalized to more complex examples
Interference-Free Regions lock(…); … unlock(…); … unlock(…); … tmp = x; … lock(…); … lock(…); … unlock(…); no acquire actions Execution trace: synchronization-free region interference-free for x no release actions
Example 1/3: Shared Mutex Our earlier example: No other thread can modify x between A and B Safe to remove the redundant read of mtx_shared A: tmp1 = mtx_shared; lock(tmp1); … B: tmp2 = mtx_shared; unlock(tmp2); B falls in A’s interference-free region.
Example 2/3: Overlapping Regions • Interference-free regions for A and B overlap, so they see the same value despite the nested critical section: • Safe to remove the redundant read of x A: tmp1 = x; lock(m); … unlock(m); B: tmp2 = x;
Access A is loop-invariant, even though there is synchronization within the loop body. Example 3/3: Loop Invariance while(…) { A: tmp1 = x; lock(m); … unlock(m); } A: tmp1 = x; lock(m); … unlock(m); while(…) { A’: tmp1 = x; lock(m); … unlock(m); } unroll loop
PROOF SKETCH [no acquires] … read(x) … [no releases] Thread 1: write(x) write(x) Other threads: happens-before
Related Work: Roach Motel Memory accesses can be moved into (not out of) critical sections Proved sound for DRF memory models by Ševčík (2008) Similar reasoning: information flows across synchronization operations in one direction … tmp1 = x; lock(m); … Original … lock(m); tmp1 = x; … Transformed
Related Work: Siloed References Joisha et al. (POPL ’11) Identify procedures for which a variable is siloed by iteratively refining a program graph Allows classical optimizations to be applied to multithreaded code Interprocedural analysis (vs. local analysis for this work) Complementary to this work {y} f() {x,y} {x} g() h()
Conclusions • Using only local analysis, we can answer interesting questions about multithreaded programs • Improve understanding of program semantics in C/C++-style memory models • Omitted: extension to barriers (thread rendezvous) • Applicable to compiler optimizations
Open Questions • Is it advisable to produce unexpected results for non-data-race-free programs by exploiting the DRF assumption? • In other words, should compilers attempt to limit most optimizations to synchronization-free regions? • Can the examples presented be exploited by memory models weaker than SC but stronger than C/C++? • E.g., eliminating the redundant read of x here: A: tmp1 = x; lock(m1); … unlock(m2); B: tmp2 = x;