COCOMO II CALCULO DE COSTOS
MENU CLIENTES
Speculative Atomics Use Cases
Multiple Locks ([64]): Some applications, such as the example shown in Listing 3.4, use multiple locks x and y. In this listing, each thread initially holds one of the locks, then releases it and loops until it obtains the other lock. If the unlock accesses are relaxed such that the lock accesses can be overlapped with them, then it is possible to initially see the lock as held, and repeatedly try to obtain the lock – a violation of SC.
Seqlocks [33]: In applications where updates are infrequent, it is often safe for a thread to load shared data without acquiring a lock because usually there are no concurrent writes. In Listing 3.5,
atomic<int> x , y ; // Thread 0 ( i n i t i a l l y h o l d s x ) . . . A = 1 ; u n l o c k x ; l o c k y ; // l o o p s u n t i l i t o b t a i n s t h e l o c k r 1 = B ; . . . // Thread 1 ( i n i t i a l l y h o l d s y ) . . . B = 1 ; u n l o c k y ; l o c k x ; // l o o p s u n t i l i t o b t a i n t h e l o c k r 2 = A ; . . .
Listing 3.4: Multiple locks example [64].
a reader speculatively loads shared data (data1, data2). If there are no concurrent writers (the common case), then the readers can safely use data1 and data2 in subsequent instructions (not shown in Listing 3.5). However, the reader must reload the shared data if a writer is concurrently updating the shared data.
Seqlocks uses a shared sequence number (seq) to synchronize the concurrent loads and stores to the shared data. A reader loads seq before and after the speculative data loads to check for concurrent writers. If the reader’s sequence numbers do not match or are odd, then there is a concurrent writer. Writers make seq odd to indicate that an update is in progress. Once the update is complete, the writer updates seq to be the next even value.
Both data and seq must be distinguished as atomics. However, as discussed previously, requir- ing SC atomics unnecessarily hurts performance. The data accesses can be relaxed – the stores only race with loads and the results of racy loads get discarded, ensuring that these races do not affect the final result. The seq accesses ensure that the final data accesses whose values are used do get properly synchronized and ordered.7
Speculative Atomics Informal Intuition
Although Multiple Locks violates SC, this violation can be ignored because it does not affect the final result. Eventually each thread will see that the other thread has released the other
7
The reader’s seq accesses can also be relaxed to acquire and release ordering; we discuss this further in Section 6.2. Note that the seq1 access uses an unusual “read-don’t-modify-write” operation (instead of a plain read) to generate
atomic<unsigned> s e q ; a t o m i c <int> data1 , d a t a 2 ; T r e a d e r ( ) { i n t r1 , r 2 ; unsigned s e q 0 , s e q 1 ; do { s e q 0 = s e q . a t o m i c l o a d ( m e m o r d e r s e q c s t ) ; r 1 = d a t a 1 . a t o m i c l o a d ( m e m o r d e r r e l a x e d ) ; r 2 = d a t a 2 . a t o m i c l o a d ( m e m o r d e r r e l a x e d ) ; s e q 1 = s e q . a t o m i c f e t c h a d d ( 0 , m e m o r d e r s e q c s t ) ; } while ( ( s e q 0 != s e q 1 ) | | ( s e q 0 & 1 ) ) ; // u s e s r 1 and r 2 } void w r i t e r ( . . . ) { unsigned s e q 0 = s e q . a t o m i c l o a d ( m e m o r d e r s e q c s t ) ; while ( ( s e q 0 & 1 ) | | ! s e q . a t o m i c c m p e x c h a n g e w e a k ( s e q 0 , s e q 0 +1) ) { ; } d a t a 1 . a t o m i c s t o r e ( . . . , m e m o r d e r r e l a x e d ) ; d a t a 2 . a t o m i c s t o r e ( . . . , m e m o r d e r r e l a x e d ) ; s e q . a t o m i c s t o r e ( s e q 0 + 2 , m e m o r d e r s e q c s t ) ; }
Listing 3.5: Seqlocks example [33].
lock, and will obtain that lock. Although relaxing Seqlocks’ loads to data1 and data2 may read some inconsistent, non-SC values, any misspeculated values will not be used because the sequence numbers will not match. Thus, speculatively accessing the shared data does not violate SC. The stores data1 and data2 can also be relaxed without violating SC because they only race with the misspeculated loads. To exploit this intuition, we formalize what it means for a racing access to be “speculative” and call such operations speculative atomics.One way to formalize this and ensure the final result is always SC is to require that values returned by racy speculative loads are never used, as in Multiple Locks and Seqlocks.8 We formalize this next.
DRFrlx Formal Definition (Version 3)
We only show the parts that change from Section 3.3.3. All memory operations must be distin- guished as data, paired, unpaired, commutative, non-ordering, or speculative.
Definitions for an SC Execution:
Speculative Race: Two operations, X and Y , form a speculative race if and only if they form a
8
This concept can be generalized to allow speculative atomics to use their returned values, but only within the speculative part of the program (so they do not affect the final result). It can also be potentially generalized to “read- copy-update” (RCU) patterns [54, 111]. These generalizations are left for future work, but exploit P Lpc’s [5, 64] observation that unessential operations can be ignored when reasoning about an execution’s DRF properties because they do not affect the final result.
atomic<unsigned long> myCount [NUM THREADS ] ; a d d s p l i t c o u n t e r ( v , tID ) {
v a l = myCount [ tID ] . a t o m i c l o a d ( m e m o r d e r r e l a x e d ) ; newVal = v a l + v ;
myCount [ tID ] . a t o m i c s t o r e ( newVal , m e m o r d e r r e l a x e d ) ; }
r e a d s p l i t c o u n t e r ( tID ) { sum = 0 ;
f o r ( i = 0 ; i < NUM THREADS; ++i ) { l o c = ( ( tID + i ) % NUM THREADS) ;
sum += myCount [ l o c ] . a t o m i c l o a d ( m e m o r d e r r e l a x e d ) ; } return sum ; } a d d s p l i t c o u n t e r ( 1 , 0 ) ; // Thread 0 r 1 = r e a d s p l i t c o u n t e r ( 1 ) ; // Thread 1 a d d s p l i t c o u n t e r ( 2 , 2 ) ; // Thread 2 r 2 = r e a d s p l i t c o u n t e r ( 3 ) ; // Thread 3
Listing 3.6: Split counters example [111].
race, at least one of X or Y is distinguished as a speculative atomic, and either:
• both operations are stores, or
• the result of the load is observed by another instruction in the execution (i.e., the returned value is used by another instruction in the thread).
Program and Model Definitions:
DRFrlx Program: A program is DRFrlx if and only if for every SC execution of its program: • all operations can be distinguished by the system as either data or as paired, unpaired,
commutative, non-ordering, or speculative atomics, and
• there are no data races, commutative races, non-ordering races, or speculative races in the execution.