10.07.2015 Views

Is Parallel Programming Hard, And, If So, What Can You Do About It?

Is Parallel Programming Hard, And, If So, What Can You Do About It?

Is Parallel Programming Hard, And, If So, What Can You Do About It?

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

148 CHAPTER 15. CONFLICTING VISIONS OF THE FUTUREseems sound, but leaves the locking design constraints(such as the need to avoid deadlock)firmly in place.5. Strive to reduce the overhead imposed on lockingprimitives.ThefactthattherecouldpossiblyaprobleminterfacingTM and locking came as a surprise to many,which underscores the need to try out new mechanismsand primitives in real-world production software.Fortunately, the advent of open source meansthat a huge quantity of such software is now freelyavailable to everyone, including researchers.15.1.8 Reader-Writer Locking<strong>It</strong> is commonplace to read-acquire reader-writerlocks while holding other locks, which just works,at least as long as the usual well-known softwareengineeringtechniques are employed to avoid deadlock.Read-acquiringreader-writerlocksfromwithinRCUread-sidecriticalsectionsalsoworks, anddoingso eases deadlock concerns because RCU read-sideprimitives cannot participated in lock-based deadlockcycles. But what happens when you attemptto read-acquire a reader-writer lock from within atransaction?Unfortunately, the straightforward approach toread-acquiring the traditional counter-based readerwriterlock within a transaction defeats the purposeof the reader-writer lock. To see this, considera pair of transactions concurrently attemptingto read-acquire the same reader-writer lock.Because read-acquisition involves modifying thereader-writer lock’s data structures, a conflict willresult, which will roll back one of the two transactions.This behavior is completely inconsistent withthe reader-writer lock’s goal of allowing concurrentreaders.Here are some options available to TM:1. Use per-CPU or per-thread reader-writer locking[HW92], which allows a given CPU (orthread, respectively) to manipulate only localdata when read-acquiring the lock. This wouldavoid the conflict between the two transactionsconcurrently read-acquiring the lock, permittingboth to proceed, as intended. Unfortunately,(1) the write-acquisition overhead ofper-CPU/thread locking can be extremely high,(2) the memory overhead of per-CPU/threadlockingcanbeprohibitive, and(3)thistransformationis available only when you have accessto the source code in question. Other morerecentscalable reader-writer locks [LLO09]might avoid some or all of these problems.2. Use TM only “in the small” when introducingTM to lock-based programs, thereby avoidingread-acquiring reader-writer locks from withintransactions.3. Set aside locking-based legacy systems entirely,re-implementing everything in terms of transactions.This approach has no shortage of advocates,but this requires that all the issues describedin this series be resolved. During thetime it takes to resolve these issues, competingsynchronization mechanisms will of course alsohave the opportunity to improve.4. Use TM strictly as an optimization inlock-based systems, as was done by theTxLinux [RHP + 07] group. This approachseems sound, but leaves the locking design constraints(such as the need to avoid deadlock)firmly in place. Furthermore, this approachcan result in unnecessary transaction rollbackswhen multiple transactions attempt to readacquirethe same lock.Of course, there might well be other non-obviousissuessurroundingcombiningTMwithreader-writerlocking, as there in fact were with exclusive locking.15.1.9 PersistenceThere are many different types of locking primitives.One interesting distinction is persistence, in otherwords, whether the lock can exist independently ofthe address space of the process using the lock.Non-persistent locks include pthread_mutex_lock(), pthread_rwlock_rdlock(), and mostkernel-level locking primitives. <strong>If</strong> the memory locationsinstantiatinganon-persistentlock’sdatastructuresdisappear, so does the lock. For typical use ofpthread_mutex_lock(), this means that when theprocess exits, all of its locks vanish. This propertycan be exploited in order to trivialize lock cleanupat program shutdown time, but makes it more difficultforunrelatedapplicationstosharelocks,assuchsharing requires the applications to share memory.Persistentlocks helpavoid theneedtosharememoryamong unrelated applications. Persistent lockingAP<strong>Is</strong> include the flock family, lockf(), SystemVsemaphores, ortheO_CREATflagtoopen(). ThesepersistentAP<strong>Is</strong>canbeusedtoprotectlarge-scaleoperationsspanning runs of multiple applications, and,

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!