1.22k likes | 1.24k Views
Understand how program analyses transform with memory access information. Learn about pointer analysis, static memory disambiguation, and detecting data race violations. This text delves into the complexities of multithreaded programs.
E N D
Program Analysis Techniquesfor Memory Disambiguation Radu Rugina and Martin Rinard Laboratory for Computer Science Massachusetts Institute of Technology
Basic Problem *p = v; (write v into the memory location that p points to) What memory location may *p=v access? Without Any Analysis: *p=v may access any location *p = v
Basic Problem *p = v; (write v into the memory location that p points to) What memory location may *p=v access? With Analysis: *p=v may access this location *p=v does not access these memory locations ! *p = v *p=v may access this location
Static Memory Disambiguation Analyze the program to characterize the memory locations that statements in the program read and write Fundamental problem in program analysis with many applications
Application: Automatic Parallelization *p = v1 *p = v1; *q = v2; *q = v2
Application: Data Race Detection ( Dual Problem ) *p = v1 *p = v1; *q = v2; || *q = v2
Application: Detection of Array Bounds Violations *p = v A[1 .. n] *p = v; . . .
Many Other Applications • Virtually all program analyses, transformations, and validations require information about how the program accesses memory • Foundation for other analyses and transformations • Understand, maintain, debug programs • Give security guarantees
Analysis Techniquesfor Memory Disambiguation Pointer Analysis Disambiguates memory accesses via pointers Symbolic Analysis Characterizes accessed subregions within dynamically allocated memory blocks
Pointer Analysis • GOAL: Statically compute where pointers may point e.g. “ p x before statement *p = 1” • Must represent points-to relations between memory locations • Complications: 1. Statically unbounded number of locations • recursive data structures (lists, trees) • dynamically allocated arrays 2. Multiple possible executions of the program • may create different dynamic data structures
Memory Abstraction Stack Heap p i head Physical Memory r v q p i head Abstract Memory q v r
Memory Abstraction Stack Heap p i head Physical Memory r v q p i head Abstract Memory q v r
Sequential vs. MultithreadedPointer Analysis • Variety of existing algorithms for sequential programs [CWZ90], [LR92], [CBC93], [And94], [EGH94], [WL95], [Ruf95], [Ste96], [DMM98] • Dataflow analysis: • Computes points-to information at each program point • Dataflow information : points-to graphs • Analyze each statement : create/kill edges • Pointer analysis for multithreaded programs • Challenging: parallel threads may concurrently update shared pointers
2 integers, 1 shared pointer: int x, y; int *p; Two concurrent threads Questions: - what location is written by *p=1? - what location is written by *p=2? OR : Q1: p? in left thread Q2: p? after both threads completed Example p = &x; parbegin *p = 1; p = &y; parend *p = 2;
Two Possible Executions p = &x; p = &x; p x p x *p = 1; p = &y; p y p = &y; *p = 1; p y *p = 2 *p = 2;
Analysis Results p = &x; p x parbegin x p p x y *p = 1; p = &y; x p p y y parend p y *p = 2;
Analysis of Multithreaded Programs • Straightforward solution (Ideal Algorithm) • Analyze all possible interleavings of statements from the parallel threads and merge the results • fails because of exponential complexity • Our approach: • Analyze threads in turn • During the analysis of each thread, take into account all edges created by parallel threads, which we call interference information
Interference Information • Interference information = points-to edges created by the other parallel threads ti ti-1 ti+1 t1 tn Interference (edges created) ... ... Parallel threads Analyzed thread
Multithreaded Analysis • Dataflow information is a triple <C, I, E> : • C = current points-to information • I = interference points-to edges from parallel threads • E = set of points-to edges created by current thread • Interference: Ik = U Ej where t1 … tn are n parallel threads • Invariant: I C • Within each thread, interference points-to edges are always added to the current information k = j
Analysis for Example p = &x; parbegin *p = 1; p = &y; parend *p = 2;
Analysis for Example p = &x; < p x , , p x > parbegin *p = 1; p = &y; parend *p = 2;
Analysis of Parallel Threads p = &x; < p x , , p x > parbegin < p x , , > < p x , , > *p = 1; p = &y; parend *p = 2;
Analysis of Parallel Threads p = &x; < p x , , p x > parbegin < p x , , > < p x , , > *p = 1; p = &y; < p x , , > parend *p = 2;
Analysis of Parallel Threads p = &x; < p x , , p x > parbegin < p x , , > < p x , , > *p = 1; p = &y; < p x , , > < p y , , p y > parend *p = 2;
Analysis of Parallel Threads p = &x; < p x , , p x > parbegin < p x , , > < p x , , > *p = 1; p = &y; < p x , , > < p y , , p y > parend *p = 2;
Analysis of Parallel Threads p = &x; < p x , , p x > parbegin x < p , p y , > < p x , , > y *p = 1; p = &y; < p y , , p y > parend *p = 2;
Analysis of Parallel Threads p = &x; < p x , , p x > parbegin x < p , p y , > < p x , , > y *p = 1; p = &y; x < p , p y , > < p y , , p y > y parend *p = 2;
Analysis of Parallel Threads p = &x; < p x , , p x > parbegin x < p , p y , > < p x , , > y *p = 1; p = &y; x < p , p y , > < p y , , p y > y parend *p = 2;
Analysis of Thread Joins p = &x; < p x , , p x > parbegin x < p , p y , > < p x , , > y *p = 1; p = &y; x < p , p y , > < p y , , p y > y parend x , , p < p y > y *p = 2;
Analysis of Thread Joins p = &x; < p x , , p x > parbegin x < p , p y , > < p x , , > y *p = 1; p = &y; x < p , p y , > < p y , , p y > y parend x , , p < p y > y *p = 2;
Final Result p = &x; < p x , , p x > parbegin x < p , p y , > < p x , , > y *p = 1; p = &y; x < p , p y , > < p y , , p y > y parend x , , p < p y > y *p = 2;
General Dataflow Equations Parent Thread < C , I , E > parbegin C U E2 C U E1 < , I U E2 , > < , I U E1 , > Thread 1 Thread 2 C1 C1 < , I U E2 , E1 > < , I U E1 , E2 > parend < C1 C2 , I , E U E1 U E2 > U Parent Thread
General Dataflow Equations Parent Thread < C , I , E > parbegin C U E2 C U E1 < , I U E2 , > < , I U E1 , > Thread 1 Thread 2 C1 C2 < , I U E2 , E1 > < , I U E1 , E2 > parend < C1 C2 , I , E U E1 U E2 > U Parent Thread
General Dataflow Equations Parent Thread < C , I , E > parbegin C U E2 C U E1 < , I U E2 , > < , I U E1 , > Thread 1 Thread 2 C1 C2 < , I U E2 , E1 > < , I U E1 , E2 > parend < C1 C2 , I , E U E1 U E2 > U Parent Thread
Overall Algorithm • Extensions: • Parallel loops • Conditionally spawned threads • Recursively generated concurrency • Flow-sensitive at intra-procedural level • Context-sensitive at inter-procedural level
Algorithm Evaluation • Soundness : • the multithreaded algorithm conservatively approximates all possible interleavings of statements from the parallel threads • Termination of fixed-point algorithms: • follows from the monotonicity of the transfer functions • Complexity of fixed-point algorithms: • worst-case polynomial complexity: O(n4), where n = number of statements • Precision of analysis: • if the concurrent threads do not (pointer-)interfere then this algorithm gives the same result as the Ideal Algorithm
Experimental Results Implementation: SUIF infrastructure, Cilk benchmarks
Precision of Pointer Analysis • Number of targets for dereferenced pointers at loads/stores: • usually unique target: 83 % of the loads, 88 % of the stores • few potentially uninitialized pointers • very few pointers with more than two targets
What Pointer Analysis Gives Us • Disambiguation of Memory Accesses Via Pointers • Pointer-based loads and stores: use pointer analysis results to derive the memory locations that each pointer-based load or store statement accesses • MOD-REF or READ-WRITE SETS Analysis: • All loads and stores • Procedures: use the memory access information for loads and stores to compute what locations each procedure accesses
Other Uses of Pointer Analysis • In the MIT RAW CC Compiler: static promotion • Promote memory accesses to the fast, static network and avoid the slow, dynamic network [Barua et al., PLDI99] • In the MIT DeepC project, a C-to-silicon compiler • Split memory in smaller memories with narrow address spaces [Babb et al., FCCM99] • Memory disambiguation for bitwidth analysis: • The Bitwise project at MIT [Stephenson and Amarasinghe, PLDI00] • The PipeWrench project at CMU [Budiu et al., EuroPar00]
Other Uses of Pointer Analysis (ctd.) • In the MIT Superword Level Parallelism project • Again, disambiguates memory for subsequent analyses [Larsen and Amarasinghe, PLDI00] • In the FlexCache project at MIT, University of Massachusetts, Amherst: • Use pointer analysis and other static analyses to eliminate a large portion of the cache-tag lookups [Moritz et al., IRAM00]
Is Pointer Analysis Always Enough to Disambiguate Memory? No
Is Pointer Analysis Always Enough to Disambiguate Memory? Pointer analysis uses a memory abstraction that merges together all elements within allocated memory blocks Sometimes need more sophisticated techniques to characterize accessed regions within allocated memory blocks
Parallel Divide and Conquer Sort 7 4 6 1 3 5 8 2
8 2 7 4 6 1 3 5 Parallel Divide and Conquer Sort 7 4 6 1 3 5 8 2 Divide
8 2 7 4 6 1 3 5 Parallel Divide and Conquer Sort 7 4 6 1 3 5 8 2 Divide 4 7 1 6 3 5 2 8 Conquer
8 2 7 4 6 1 3 5 Parallel Divide and Conquer Sort 7 4 6 1 3 5 8 2 Divide 4 7 1 6 3 5 2 8 Conquer 1 4 6 7 2 3 5 8 Combine