Software Transactional Memory
Total Page:16
File Type:pdf, Size:1020Kb
Software Transactional Memory Jaakko Järvi University of Bergen <2018-10-02 Tue> Jaakko Järvi (University of Bergen) Software Transactional Memory <2018-10-02 Tue> 1 / 11 Outline 1 Examples Jaakko Järvi (University of Bergen) Software Transactional Memory <2018-10-02 Tue> 2 / 11 Both transactions maintain invariant, yet without early fail can “crash” Examples Early Rollback is Important Assume invariant x == 0 && y == 0, and two concurrently executing threads: atomic { if (x != y) crash(); } atomic { ++x; ++y; } Jaakko Järvi (University of Bergen) Software Transactional Memory <2018-10-02 Tue> 3 / 11 Examples Early Rollback is Important Assume invariant x == 0 && y == 0, and two concurrently executing threads: atomic { if (x != y) crash(); } atomic { ++x; ++y; } Both transactions maintain invariant, yet without early fail can “crash” Jaakko Järvi (University of Bergen) Software Transactional Memory <2018-10-02 Tue> 3 / 11 Examples Deposit with lock synchronization (Java) public void deposit(double amount){ System.out.println("Depositing "+ amount); double nb=0; balanceChangeLock.lock(); try{ nb= balance+ amount; balance= nb; } finally{ balanceChangeLock.unlock(); } System.out.println("New balance is "+ nb); } Jaakko Järvi (University of Bergen) Software Transactional Memory <2018-10-02 Tue> 4 / 11 Examples Deposit with STM (hypothetical Java) public void deposit(double amount){ System.out.println("Depositing "+ amount); double nb=0; atomic{ nb= balance+ amount; balance= nb; } System.out.println("New balance is "+ nb); } Jaakko Järvi (University of Bergen) Software Transactional Memory <2018-10-02 Tue> 5 / 11 Lock all accounts Manually decide what needs to be undone after each kind of exception Side-effects might be visible in other threads before undone Examples Composing critical sections (lock syncrhonization) class Bank{ Accounts accounts; ... void transfer(String name1, String name2, int amount){ synchronized(accounts){ try{ accounts.put(name1, accounts.get(name1)-amount); accounts.put(name2, accounts.get(name2)+amount); } catch(Exception1) {..} catch(Exception2) {..} } ... } Jaakko Järvi (University of Bergen) Software Transactional Memory <2018-10-02 Tue> 6 / 11 Examples Composing critical sections (lock syncrhonization) class Bank{ Accounts accounts; ... void transfer(String name1, String name2, int amount){ synchronized(accounts){ try{ accounts.put(name1, accounts.get(name1)-amount); accounts.put(name2, accounts.get(name2)+amount); } catch(Exception1) {..} catch(Exception2) {..} } ... } Lock all accounts Manually decide what needs to be undone after each kind of exception Side-effects might be visible in other threads before undone Jaakko Järvi (University of Bergen) Software Transactional Memory <2018-10-02 Tue> 6 / 11 Examples Composing critical sections (STM) class Bank{ Accounts accounts; ... void transfer(String name1, String name2, int amount){ try{ atomic{ accounts.put(name1, accounts.get(name1)-amount); accounts.put(name2, accounts.get(name2)+amount); } } catch(Exception1) {..} catch(Exception2) {..} } ... } Jaakko Järvi (University of Bergen) Software Transactional Memory <2018-10-02 Tue> 7 / 11 Examples Motivating example: HashMap (thread-unsafe) public Object get(Object key){ int idx= hash(key); // Compute hash HashEntry e= buckets[idx]; // to find bucket while(e != null){ // Find element in bucket if(key.equals(e.key)) returne.value; e=e.next; } return null; } Jaakko Järvi (University of Bergen) Software Transactional Memory <2018-10-02 Tue> 8 / 11 Simple solution: add a synchronization layer Poor scalability, entire map locked at once. Examples HashMap (thread-safe via lock synchronization) public Object get(Object key){ synchronized(mutex) // mutex guards all accesses to map m { returnm.get(key); } } Jaakko Järvi (University of Bergen) Software Transactional Memory <2018-10-02 Tue> 9 / 11 Examples HashMap (thread-safe via lock synchronization) public Object get(Object key){ synchronized(mutex) // mutex guards all accesses to map m { returnm.get(key); } } Simple solution: add a synchronization layer Poor scalability, entire map locked at once. Jaakko Järvi (University of Bergen) Software Transactional Memory <2018-10-02 Tue> 9 / 11 Equally simple Good scalability, only the impacted parts of HashMap locked (briefly) Examples HashMap (thread-safe via STM) public Object get(Object key){ atomic // System guarantees atomicity { returnm.get(key); } } Jaakko Järvi (University of Bergen) Software Transactional Memory <2018-10-02 Tue> 10 / 11 Examples HashMap (thread-safe via STM) public Object get(Object key){ atomic // System guarantees atomicity { returnm.get(key); } } Equally simple Good scalability, only the impacted parts of HashMap locked (briefly) Jaakko Järvi (University of Bergen) Software Transactional Memory <2018-10-02 Tue> 10 / 11 Examples HashMap (scalable thread-safe with fine-grained locking) public Object get(Object key){ int hash= hash(key); // Try first without locking... Entry[] tab= table; int index= hash&(tab.length-1); Entry first= tab[index]; Entry e; for(e= first;e != null;e=e.next){ if(e.hash == hash&& eq(key,e.key)){ Object value=e.value; if(value != null) return value; else break; } } // Recheck under synch if key not there or interference Segment seg= segments[hash& SEGMENT_MASK]; synchronized(seg){ tab= table; index= hash&(tab.length-1); Entry newFirst= tab[index]; if(e != null || first != newFirst){ for(e= newFirst;e != null;e=e.next){ if(e.hash == hash&& eq(key,e.key)) returne.value; } } return null; } } Jaakko Järvi (University of Bergen) Software Transactional Memory <2018-10-02 Tue> 11 / 11 Concurrent Programming in Standard C++ Jaakko Järvi University of Bergen <2018-10-02 Tue> Jaakko Järvi (University of Bergen) Concurrent Programming in Standard C++ <2018-10-02 Tue> 1 / 92 Outline 1 C++ Standardization and concurrency 2 C++ memory model 3 Standard library offerings for concurrency 4 Threads 5 Synchronizing threads with mutexes 6 Condition variables 7 Thread local variables, call once functions 8 Atomics 9 Tasks Jaakko Järvi (University of Bergen) Concurrent Programming in Standard C++ <2018-10-02 Tue> 2 / 92 C++ Standardization and concurrency C++11, C++14, C++17, C++2a, . and concurrency C++03 had no support for concurrency All concurrent programs relied on OS specific services that could change from version to version C++11 made two significant additions: a memory model for C++ the beginnings of the standard API for concurrency-related functionality threads, locks, futures, etc. C++14 adds some tweaks to the API C++17 parallel STL algorithms C++2a will add more features composable futures? coroutines? tansactional memory? latches, barriers? atomic smart pointers? Jaakko Järvi (University of Bergen) Concurrent Programming in Standard C++ <2018-10-02 Tue> 3 / 92 C++ memory model Outline 1 C++ Standardization and concurrency 2 C++ memory model 3 Standard library offerings for concurrency 4 Threads 5 Synchronizing threads with mutexes 6 Condition variables 7 Thread local variables, call once functions 8 Atomics 9 Tasks Jaakko Järvi (University of Bergen) Concurrent Programming in Standard C++ <2018-10-02 Tue> 4 / 92 For the programmer: a set of guarantees about the order in which memory reads and writes are observed by a thread conversely, a set of obligations that a programmer has to adhere to when writing concurrent code For the compiler and hardware: a set of rules that defines valid code transformations C++ memory model Memory model Memory model defines the semantics of shared variables Jaakko Järvi (University of Bergen) Concurrent Programming in Standard C++ <2018-10-02 Tue> 5 / 92 C++ memory model Memory model Memory model defines the semantics of shared variables For the programmer: a set of guarantees about the order in which memory reads and writes are observed by a thread conversely, a set of obligations that a programmer has to adhere to when writing concurrent code For the compiler and hardware: a set of rules that defines valid code transformations Jaakko Järvi (University of Bergen) Concurrent Programming in Standard C++ <2018-10-02 Tue> 5 / 92 C++ memory model Multi-processor system Thread 1 Thread n ··· r w r w Shared memory Multiple threads can update and access the same shared variables global variables, “static” class members, all data accessible to those variables or passed to the thread by other means Each thread also has its own local variables Jaakko Järvi (University of Bergen) Concurrent Programming in Standard C++ <2018-10-02 Tue> 6 / 92 C++ memory model Consistency in multi-processor systems Lamport: How to make a Multiprocessor Computer That Correctly Executes Multiprocess programs, 1979: Definitions for what consistency means in a multi-processor systems; what kind of leeway can be given to compilers and hardware Sequential processor The result of the execution is the same as if the operations had been executed in the order specified by the program Sequential consistency The result of any execution is the same as if the operations of all the processors were executed in some sequential order, and the operations of each individual processor appear in this sequence in the order specified by its program. Jaakko Järvi (University of Bergen) Concurrent Programming in Standard C++ <2018-10-02 Tue> 7 / 92 C++ memory model Sequential consistency Any execution that does something like in the lower picture must be indistinguishable from some execution like the upper picture Jaakko Järvi (University of Bergen) Concurrent Programming in Standard C++ <2018-10-02 Tue> 8