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.

150 CHAPTER 15. CONFLICTING VISIONS OF THE FUTUREthis problem, or resign themselves to a world whereTM is but one tool of several in the parallel programmer’stoolbox. (To be fair, a number of TMproponents have long since resigned themselves to aworld containing more than just TM.)15.1.11 DebuggingThe usual debugging operations such as breakpointswork normally within lock-based critical sectionsand from RCU read-side critical sections. However,in initial transactional-memory hardware implementations[DLMN09] an exception within a transactionwillabortthattransaction, whichinturnmeansthatbreakpoints abort all enclosing transactions<strong>So</strong> how can transactions be debugged?1. Usesoftwareemulationtechniqueswithintransactionscontaining breakpoints. Of course, itmight be necessary to emulate all transactionsany time a breakpoint is set within the scopeof any transaction. <strong>If</strong> the runtime system is unableto determine whether or not a given breakpointis within the scope of a transaction, thenit might be necessary to emulate all transactionsjust to be on the safe side. However,this approach might impose significant overhead,whichmightinturnobscurethebugbeingpursued.2. Use only hardware TM implementations thatare capable of handling breakpoint exceptions.Unfortunately, as of this writing (September2008), all such implementations are strictly researchprototypes.3. Use only software TM implementations, whichare (very roughly speaking) more tolerant of exceptionsthan are the simpler of the hardwareTM implementations. Of course, software TMtends to have higher overhead than hardwareTM, so this approach may not be acceptable inall situations.4. Program more carefully, so as to avoid havingbugs in the transactions in the first place. Assoon as you figure out how to do this, please dolet everyone know the secret!!!There is some reason to believe that transactionalmemory will deliver productivity improvementscompared to other synchronization mechanisms,but it does seem quite possible that these improvementscould easily be lost if traditional debuggingtechniques cannot be applied to transactions.This seems especially true if transactional memoryis to be used by novices on large transactions. Incontrast, macho “top-gun” programmers might beable to dispense with such debugging aids, especiallyfor small transactions.Therefore, if transactional memory is to deliveron its productivity promises to novice programmers,the debugging problem does need to be solved.15.1.12 The exec() System CallOne can execute an exec() system call while holdinga lock, and also from within an RCU read-sidecritical section. The exact semantics depends on thetype of primitive.In the case of non-persistent primitives (includingpthread_mutex_lock(), pthread_rwlock_rdlock(), and RCU), if the exec() succeeds, thewhole address space vanishes, along with any locksbeing held. Of course, if the exec() fails, the addressspace still lives, so any associated locks wouldalso still live. A bit strange perhaps, but reasonablywell defined.On the other hand, persistent primitives (includingtheflockfamily, lockf(), System Vsemaphores,and the O_CREAT flag to open()) would survive regardlessof whether the exec() succeeded or failed,so that the exec()ed program might well releasethem.Quick Quiz 15.1: <strong>What</strong> about non-persistentprimitives represented by data structures in mmap()regions of memory? <strong>What</strong> happens when their is anexec() within a critical section of such a primitive?<strong>What</strong> happens when you attempt to execute anexec() system call from within a transaction?1. Disallow exec() within transactions, so thatthe enclosing transactions abort upon encounteringthe exec(). This is well defined, butclearly requires non-TM synchronization primitivesfor use in conjunction with exec().2. Disallow exec() within transactions, with thecompiler enforcing this prohibition. There isa draft specification for TM in C++ thattakes this approach, allowing functions to bedecorated with the transaction_safe andtransaction_unsafe attributes. 3 This approachhas some advantages over aborting thetransaction at runtime, but again requires non-TM synchronization primitives for use in conjuntionwith exec().3 Thanks to Mark Moir for pointing me at this spec, andto Michael Wong for having pointed me at an earlier revisionsome time back.

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

Saved successfully!

Ooh no, something went wrong!