runtime/mercury_atomic_ops.h:
clang provides the GCC builtin function __sync_synchronize(); use that
as a fallback memory barrier.
Avoid unreadable #error directive output from clang.
Add an XXX about C11 atomic ops.
runtime/mercury_atomic_ops.h:
As above; on aarch64-apple-darwin we were *not* getting the error about
memory fence operations not being defined when using clang as the C
compiler; compilation was instead aborting later due to MR_SFENCE
not being defined.
Discussion of these changes can be found on the Mercury developers
mailing list archives from June 2018.
COPYING.LIB:
Add a special linking exception to the LGPL.
*:
Update references to COPYING.LIB.
Clean up some minor errors that have accumulated in copyright
messages.
runtime/*.[ch]:
trace/*.[chyl]:
As above. In some places, improve comments, e.g. by expanding contractions
such as "we've". Add #ifndef guards against double inclusion around
the trace/*.h files that did not already have them.
tools/*:
Make the corresponding changes in shell scripts that generate .[ch] files
in the runtime.
tests/*:
Conform to a slight change in the text of a message.
Move all .h and .c files to four-space indentation without tabs,
if they weren't there already.
Use the same vim line for all .h and .c files.
Align all backslashes at the ends of lines in macro definitions.
Align close comment signs.
In some places, fix inconsistent indentation.
Fix a bunch of comments. Add XXXs to a few of them.
used. Mercury's ThreadScope support will now use gettimeofday() by
default, but use of the TSC may be enabled.
Note that in Linux, gettimeofday() does not always make a system call.
runtime/mercury_threadscope.[ch]:
Add support for measuring time with gettimeofday().
Use gettimeofday() to measure time by default.
runtime/mercury_atomic_ops.[ch]
Add a new function MR_tsc_is_sensible(), It returns true if the TSC can
(as far as the RTS can detect) be used.
Fix trailing whitespace.
runtime/mercury_wrapper.c:
Add a new runtime option --threadscope-use-tsc.
When specified this option allows threadscope to use the CPU's TSC to
measure time.
doc/userguide.texi:
Document the --threadscope-use-tsc option. This documentation is
commented out.
Estimated hours taken: 1
Branches: main
Post-commit review of Paul's change introducing the loop control primitives.
It also updates some documentation Paul's update did not touch.
library/par_buildin.m:
runtime/mercury_atomic_ops.h:
runtime/mercury_context.h:
Fix formatting and grammar.
runtime/mercury_par_builtin.[ch]:
Use a variable length array in the loop control struct to store
the loop control slots. This setup needs one load to access a slot,
compared to two with the previous arrangement.
Fix formatting and grammar.
Add XXXs where relevant.
Branches: main, 11.07
Make none.par.gc bootstrap with clang (2.8.0) on Linux.
runtime/mercury_atomic_ops.h:
Define MR_ATOMIC_DEC_INT_BODY and MR_ATOMIC_DEC_AND_IS_ZERO_WORD_BODY
for clang - we use the same inline assembler definitions that are used
for GCC.
Branches: main, 11.07
Make hlc.par.gc bootstrap with clang on Linux.
runtime/mercury_atomic_ops.h:
Use the GCC definitions of MR_COMPARE_AND_SWAP_WORD_BODY and
MR_CPU_SFENCE with clang.
Branches: main, 11.07
Avoid using the __GNUC__ macro in the runtime as a test for the presence of
gcc, since clang also defines that macro. Since clang doesn't support all
of the GNU C extensions, we can't actually use __GNUC__ without also checking
whether we are actually using clang.
runtime/mercury_conf_param.h:
Add three new macros, MR_CLANG, MR_GNUC and MR_MSVC that are defined
only when the C compiler is clang, gcc, or Visual C respectively.
(In particular, MR_GNUC will _not_ be defined when the C compiler
is clang.)
runtime/mercury.c:
runtime/mercury.h:
runtime/mercury_atomic_ops.c:
runtime/mercury_atomic_ops.h
runtime/mercury_bitmap.h:
runtime/mercury_float.h:
runtime/mercury_getopt.c:
runtime/mercury_goto.h:
runtime/mercury_heap.h:
runtime/mercury_std.h:
Replace uses of the __GNUC__ and __clang__ macros with the above.
runtime/mercury_regs.h:
As above, also #include mercury_conf_param.h directly since
this file is #included by some of the tests in the configure
script.
The main benefits of these changes are:
Stack segments (and other memory zones) are cached when they are released
and can be re-used.
Some thread safety-fixes have been added.
All stack segments on all stacks are now the same size:
Small contexts (which had small stacks) aren't used with stack
segments.
The first segment on any stack is the same size as any other segment.
The first segment on any stack no-longer has a redzone.
Hard zones on all memory zones have been set to the minimum of one page
rather than one MR_unit which is usually two pages.
The caching of stack segments results in the following benchmark results. The
benefit is negligible under normal circumstances, but becomes important when
small segment sizes are used. Small segment sizes are common in
asm_fast.gc.par.stseg configurations as they reduce the memory required for
suspended contexts.
Non-segmented stack (32MB)
asm_fast.gc average of 5 with ignore=1 18.16 (1.00)
With 512KB (normal) segments:
asm_fast.gc.stseg and NO caching average of 5 with ignore=1 19.20 (1.06)
asm_fast.gc.stseg WITH caching average of 5 with ignore=1 19.16 (1.06)
With 4KB segments:
asm_fast.gc.stseg and NO caching average of 5 with ignore=1 20.66 (1.14)
asm_fast.gc.stseg WITH caching average of 5 with ignore=1 19.66 (1.08)
Other changes include corrections in code comments, clearer function names and
a documentation fix.
runtime/mercury_memory_zones.h:
runtime/mercury_memory_zones.c:
Re-write a lot of the code that managed the zone lists. The old code did
not re-use previously allocated but saved zones. The changes ensure that
MR_create_or_reuse_zone (formerly MR_create_zone) checks for a free zone
of at least the required size before allocating a new one. When zones are
released they are put on the free list.
As above MR_create_zone is now MR_create_or_reuse_zone,
MR_unget_zone is now MR_release_zone.
MR_construct_zone has been removed, it was only ever called by
MR_create_or_reuse_zone. MR_create_or_reuse_zone now contains the code for
MR_construct_zone.
To avoid an unnecessary sychronisation in parallel code some zones are not
added to the used list. The only zones put on the used list are those that
are useful to have on the used list because they have a non-default signal
handler or a redzone.
Updates to used_memory_zones now use a pthread mutex so that only one
thread may be updating the list at once. This lock is shared with the
free_memory_zones structure.
Updates to used_memory_zones now use memory barriers to guarantee that
concurrent reads always read a consistent, but possibly incomplete,
data-structure. This is necessary because it is read from a signal handler
which cannot call pthread_mutex().
Rename MR_get_used_memory_zones() to MR_get_used_memory_zones_readonly()
and document that the zone lists may be incomplete.
Make the MR_zone_next field of the MR_MemoryZone_Struct structure volatile.
Remove MAX_ZONES, it wasn't being used anywhere.
Insert some calls to MR_debug_log_message to help with debugging.
Use the correct printf integer length modifier for MR_Unsigned values.
Rename MR_context_id_counter to zone_id_counter, protect it with a lock in
HLC thread safe grades and use atomic operations in LLC thread-safe
grades..
The offset at which we start using a memory zone is allocated in sequence
from a table. This table was protected by Mercury's global lock, this is
now a CAS operation which prevents deadlocks when using trail segment,
parallel grades.
runtime/mercury_stacks.c:
Conform to changes in mercury_memory_zones.c.
Use MR_debug_log_message for printf-style debugging rather than printf.
runtime/mercury_wrapper.h:
runtime/mercury_wrapper.c:
Remove support for the smaller sized stacks in grades with stack segments.
Disable redzones when using stack segments. The MR_(non)detstack_zone_size
variables affect the first segment on every stack. Regardless of the type
of contaxt that owns that stack.
Conform to changes in runtime/mercury_memory_zones.h.
runtime/mercury_context.h:
runtime/mercury_context.c:
Removed an extra declaration for MR_init_context_maybe_generator
Small contexts are problematic since it's unclear to the programmer which
computations will be executed on smaller contexts and therefore whether
their stacks would overflow.
Conform to changes in runtime/mercury_memory_zones.h.
Conform to changes in runtime/mercury_wrapper.h.
runtime/mercury_memory.c:
Adjust the definition of MR_unit. It is now guaranteed to be a multiple of
the page size which is required by its use in mercury_memory_zones.c
Conform to changes in mercury_wrapper.h.
runtime/mercury_engine.c:
runtime/mercury_memory_handlers.c:
runtime/mercury_trail.c:
Conform to changes in runtime/mercury_memory_zones.h.
runtime/mercury_memory_handlers.c:
Use the correct printf integer length modifier for MR_Unsigned values.
runtime/mercury_misc.c:
Print out the meaning of errno if it is nonzero in MR_fatal_error.
Use the correct printf integer length modifier for MR_Unsigned values.
runtime/mercury_atomic_ops.h:
Define MR_THREADSAFE_VOLATILE to expand to volatile when MR_THREADSAFE is
defined. Otherwise it expands to nothing.
Make memory fences macros and atomic operations available in all thread safe
grades, not just low level C grades.
doc/user_guide.texi:
Corrected the default detstack size.
parallel and threadscope grades.
We had been using types with the wrong signedness well calling atomic operations.
GCC 4.x also picked up an error where #elif was used instead of #else.
While testing these changes on a 32bit system more bugs where found on the i386
architecture and on AMD brand processors.
runtime/mercury_atomic_ops.h:
runtime/mercury_atomic_ops.c:
Add unsigned variants of the following atomic operations:
increment,
add,
add_and_fetch,
dec_and_is_zero,
Add a signed variant for compare and swap.
Rename the MR_atomic_dec_<type>_and_is_zero operation to move the type to
the end of the name.
Use volatile storage in the MR_Stats structure.
A 32bit machine cannot do atomic operations on 64bit values and MR_Stats
must use 64bit values. Therefore 64bit values in the MR_Stats structure
are now protected by a lock on 32bit machines.
runtime/mercury_atomic_ops.h:
Fix a typeo in the i386 version of MR_atomic_dec_and_is_zero_uint().
runtime/mercury_atomic_ops.c:
AMD CPUs do not conform to Intel's specification for being able to
extract the CPU clock speed from the brand string. When we cannot
determine the CPU's clock speed then we write out threadscope
timestamps in raw clock cycles rather than nanoseconds.
On i386 machines the ebx register is used to implement PIC code,
however the CPUID instruction uses it to output information. Save
this register on C's stack while we issue CPUID and retrieve the
result in ebx.
We now pass native machine sized values to the inline assembler code
that implements RDTSC and RDTSCP.
Fix commenting style in some places.
runtime/mercury_atomic_ops.c:
Fix some incorrect C preprocessor code for conditional compilation.
runtime/mercury_grade.h:
Increment binary compatibility number. This should have been done in a
prior change when the MR_runnext macro changed which broke binary
compatibility in the parallel low-level C grades.
runtime/mercury_context.h:
In MR_SyncTerm_Struct use an unsigned value for the number of conjuncts
remaining before the conjunction is complete.
runtime/mercury_threadscope.c:
Record raw cpu clock ticks rather than milliseconds when we don't
know the processor's clock speed.
runtime/mercury_context.c:
runtime/mercury_wsdeque.h:
runtime/mercury_wsdeque.c:
Conform to changes in mercury_atomic_ops.h
currently holding it did not allocate a new context ID. A user looking at
this behaviour from threadscope would see thread 27 (for instance) finish, and
then immediately begin executing again. Therefore we now allocates a new
context ID when a context is reused making the context look different from
threadscope's point of view. New context IDs are already allocated to
contexts that are allocated from the free context lists.
runtime/mercury_context.c:
As above.
The next context id variable is now accessed atomically rather than being
protected by the free context list lock.
runtime/mercury_atomic_ops.h:
runtime/mercury_atomic_ops.c:
Implement a new atomic operation, MR_atomic_add_and_fetch_int, this is
used to allocate context ids.
Reimplement MR_atomic_add_int in terms of MR_atomic_add_and_fetch_int when
handwritten assembler support is not available.
runtime/mercury_atomic_ops.c:
Re-order atomic operations to match the order in the header file.
runtime/mercury_atomic_ops.h:
Place the definition of the MR_ATOMIC_PAUSE macro before the other atomic
operations since MR_atomic_add_and_fetch_int depends on it. This also
conforms with the coding standard.
runtime/mercury_threadscope.h:
Make the Context ID type a MR_Integer to match the argument size on the
available atomic operations.
code selection.
runtime/mercury_atomic_ops.h:
runtime/mercury_conf_param.h:
Updated contents and prose used in comments to make them more clear.
Updated formatting of comments.
This change introduces three new C preprocessor macros that can be used to
override which code is used to implement atomic operations. This allows us to
test more portable but less efficient code on platforms that support the
efficient code.
runtime/mercury_atomic_ops.h:
Fix the bug.
Introduce extra declarations that control which implementation of atomic
operations is selected.
Re-order code, so that all the declarations occur before any definitions.
This fixes another bug that was uncovered by the new macros.
runtime/mercury_conf_param.h:
Document the new macros.
Threadscope grades are enabled by using the grade component 'threadscope'.
They are supported only with low-lavel C parallel grades. Support for
threadscope in high level C grades is intended in the future but does not work
now.
runtime/mercury_conf_param.h:
Create the MR_THREADSCOPE macro that is defined if the grade is a
threadscope grade.
Define MR_PROFILE_FOR_PARALLEL_EXECUTION if MR_THREADSCOPE is defined.
Emit an error if MR_LL_PARALLEL_CONJ is defined before it is implied by
MR_THREADSAFE and ! MR_HIGHLEVEL_CODE
runtime/mercury_grade.h
Update the grade symbol for the threadscope grade component.
runtime/mercury_atomic_ops.c:
runtime/mercury_atomic_ops.h:
runtime/mercury_context.c:
runtime/mercury_context.h:
runtime/mercury_engine.c:
runtime/mercury_engine.h:
runtime/mercury_thread.c:
runtime/mercury_threadscope.c:
runtime/mercury_threadscope.h:
runtime/mercury_wrapper.c:
Now that MR_PROFILE_FOR_IMPLICIT_PARALLELISM is implied by MR_THREADSAFE we
don't need to test for MR_THREADSAFE when we test for
MR_PROFILE_FOR_IMPLICIT_PARALLELISM. The same is true for
MR_LL_PARALLEL_CONJ which is implied by MR_THREADSAFE &&
!MR_HIGHLEVEL_CODE.
Replace some occurances of MR_PROFILE_FOR_IMPLICIT_PARALLELISM with
MR_THREADSCOPE where the conditionally compiled code is used to support
threadscope profiling.
scripts/init_grade_options.sh-subr:
scripts/canonical_grade.sh-subr:
scripts/parse_grade_options.sh-subr:
scripts/final_grade_options.sh-subr:
scripts/mgnuc.in:
compiler/handle_options.m:
compiler/options.m:
compiler/compile_target_code.m:
configure.in:
Add support for the new grade component.
Pass -DMR_THREADSCOPE to the C compiler when using a threadscope grade.
Add assertions to ensure that the 'threadscope' grade component is used
only with the 'par' grade component.
doc/user_guide.texi:
Added commented-out documentation for the threadscope greate component.
Adjusted documentation of the --profile-parallel-execution runtime option
to describe the correct prerequisite compile time options.
Added my name to the authors list.
runtime/mercury_context.c:
Corrected grammar and prose in comments in the MR_do_join_and_continue code.
This patch is heavily based on earlier, uncommitted work by Peter Wang. It
has been updated so that it applies against the current version of the source.
A number of other changes have been made. Peter's original ChangeLog
follows:
Implement work stealing for parallel conjunctions. This builds on an
older patch which introduced work-stealing deques to the runtime but
didn't perform work stealing.
Previously when we came across a parallel conjunct, we would place a spark
into either the _global spark queue_ or the _local spark stack_ of the
Mercury context. A spark on the global spark queue may be picked up for
parallel execution by an idle Mercury engine, whereas a spark on a local
spark stack is confined to execution in the context that originated it.
The problem is that we have to decide, ahead of time, where to put a
spark. Ideally, we should have just enough sparks in the global queue to
keep the available Mercury engines busy, and leave the rest of the sparks
to execute in their original contexts since that is more efficient. But
we can't predict the future so have to make do with guesses using simple
heuristics. A bad decision, once made, cannot be reversed. An engine may
sit idle due to an empty global spark queue, even while there are sparks
available in some local spark stacks.
In the work stealing scheme, sparks are always placed into each context's
_local spark deque_. Idle engines actively try to steal sparks from
random spark deques. We don't need to make irreversible and potentially
suboptimal decisions about where to put sparks. Making a spark available
for parallel execution is cheap and happens by default because of the
work-stealing deques; putting a spark on a global queue implies
synchronisation with other threads. The downside is that idle engines
need to expend more time and effort to find the work from multiple places
instead of just one place.
Practically, the new scheme seems to work as well as the old scheme and
vice versa, except that the old scheme often required
`--max-context-per-threads' to be set "correctly" to get good results.
Only tested on x86-64, which has a relatively constrained memory model.
My modifications include:
The difference between 'shared' and 'private' synchronisation terms has
been removed. All sync terms are assumed to be shared and thread-safe
operations are used everywhere. This allows us to remove complicated code
used when a private synchronisation term became shared. This may change
the performance of thread stealing, in particular it may become slower due
to the assumption that all sync terms are shared and therefore atomic
operations must always be used when decrementing their count field.
I've re-factored MR_do_join_and_continue, It is now much simpler as the
conditional code in it enumerates the possible cases clearly.
This change bootchecks and successfully runs the test suite in asm_fast.gc
asm_fast.gc.par hlc.gc and hlc.par, no other grades where tested. I have not
yet tested performance.
runtime/mercury_context.c:
runtime/mercury_context.h:
Keep pointers to all spark deques in a flat array, so we have access
to them for stealing.
Added functions to manage the global array of spark deques.
Modify MR_do_run_next, it now attempts to steal work from other context's
spark queues. Threads sleeping on the condition variable in
MR_do_run_next now use a timed wait so they can wakeup and try to steal
sparks.
Re-factored MR_do_join_and_continue.
MR_num_idle_engines is used by atomic operations, it has been made an
MR_Integer so that it's size matches the expectations of the atomic
operations we have defined.
Modified the MR_SyncTerm and MR_Spark structures. Sparks now point to
their sync terms. The perant stack pointer has been moved into the
SyncTerm structure. The MR_st_is_shared field in the MR_SyncTerm
structure has been removed.
runtime/mercury_atomic_ops.c:
runtime/mercury_atomic_ops.h:
Implement a new atomic operation: decrement integer and is zero. On the
x86/x86_64 one can't atomically decrement an integer and fetch the result
in a single instruction, a loop with a 'compare and exchange' instruction
is necessary. However since we only want to test if the value has become
zero after the decrement we can use the processor's flags. This can be
done in two instructions, but more importantly a loop is not required and
only one instruction is atomic.
runtime/mercury_wrapper.c:
runtime/mercury_wrapper.h:
Added runtime tunable options for work stealing. These control the number
of attempts an idle engine will make when looking for work, and the
duration to sleep after failing to find any work.
runtime/mercury_thread.c:
runtime/mercury_thread.h:
Added MR_COND_TIMED_WAIT, which waits on condition variables like
MR_COND_WAIT except that it may time out.
runtime/mercury_wsdeque.h:
runtime/mercury_wsdeque.c:
MR_wsdeque_pop_bottom now uses it's second argument to return the code
address to jump to rather the whole spark.
runtime/mercury_conf.h.in:
configure.in:
Test for sched_yield()
Change the synchronisation term structure.
doc/user_guide.texi:
Add commented out documentation for two new tunable parameters,
`--worksteal-max-attempts' and `--worksteal-sleep-msecs'.
Implementors may want to experiment with different values but end
users shouldn't need to know about them.
This change adds support for threadscope profiling of the parallel runtime in
low level C grades. It can be enabled by compiling _all_ code with the
MR_PROFILE_PARALLEL_EXECUTION_SUPPORT C macro defined. The runtime, libraries
and applications must all have this flag defined as it alters the MercuryEngine
and MR_Context structures.
See Don Jones Jr, Simon Marlow, Satnam Singh - Parallel Performance Tuning for
Haskell.
This change also includes:
Smarter thread pinning (the primordial thread is pinned to the thread that
it is currently running on).
The addition of callbacks from the Boehm GC to notify the runtime of
stop the world garbage collections.
Implement some userspace spin loops and conditions. These are cheaper than
their POSIX equivalents, do not support sleeping, and are signal handler
safe.
boehm_gc/alloc.h:
boehm_gc/alloc.c:
Declare and define the new callback functions.
boehm_gc/alloc.c:
Call the start and stop collect callbacks when we start and stop a
stop-the-world collection.
Correct how we record the time spent collecting, it now includes
collections that stop prematurely.
boehm_gc/pthread_stop_world.c:
Call the pause and resume thread callbacks in each thread where the GC
arranges for that thread to be stopped during a stop-the-world collection.
runtime/mercury_threadscope.c:
runtime/mercury_threadscope.h:
New files implementing the threadscope support.
runtime/mercury_atomic_ops.c:
runtime/mercury_atomic_ops.h:
Rename MR_configure_profiling_timers to MR_do_cpu_feature_detection.
Add a new function MR_read_cpu_tsc() to read the TSC register from the CPU,
this simply abstracts the static MR_rdtsc function.
runtime/mercury_atomic_ops.h:
Modify the C inline assembler to ensure we tell the C compiler that the
value in the register mapped to the 'old' parameter is also an output from
the instructions. That is, the C compiler must not depend on the value of
'old' being the same before and after the instruction is executed. This
has never been a problem in practice though.
Implement some cheap userspace mutual exclusion locks and condition
variables. These will be faster than pthread's mutexes when critical
sections are short and threads are pinned to separate CPUs.
runtime/mercury_context.c:
runtime/mercury_context.h:
Add a new function for pinning the primordial thread. If the OS supports
sched_getcpu we use it to determine which CPU the primordial thread should
use. No other thread will be pinned to this CPU.
Add a numeric id field to each context, this id is uniquely assigned and
identifies each context for threadscope.
MR_schedule_context posts the 'context runnable' threadscope event.
MR_do_runnext has been modified to destroy engines differently, it ensures
they cleanup properly so that their threadscope events are flushed properly
and then calls pthread_exit(0)
MR_do_runnext posts events for threadscope.
MR_do_join_and_continue posts events for threadscope.
runtime/mercury_engine.h:
Add new fields to the MercuryEngine structure including a buffer of
threadscope events, a clock offset (used to synchronize the TSC clocks) and
a unique identifier for the engine,
runtime/mercury_engine.c:
Call MR_threadscope_setup_engine() and MR_threadscope_finalize_engine for
newly created and about-to-be-destroyed engines.
When the main context finishes on a thread that's not the primordial thread
post a 'context is yielding' message before re-scheduling the context on
the primordial thread.
runtime/mercury_thread.c:
Added an XXX comment about a potential problem, it's only relevant for
programs using thread.spawn.
Added calls to the TSC synchronisation code used for threadscope profiling.
It appears that this is not necessary on modern x86 machines, it has been
commented out.
Post a threadscope event when we create a new context.
Don't call pthread_exit in MR_destroy_thread, we now do this in
MR_do_runnext so that we can unlock the runqueue mutex after cleaning up.
runtime/mercury_wrapper.c:
Conform to changes in mercury_atomic_ops.[ch]
Post an event immediately before calling main to mark the beginning of the
program in the threadscope profile.
Post a "context finished" event at the end of the program.
Wait until all engines have exited before cleaning up global data, this is
important for finishing writing the threadscope data file.
configure.in:
runtime/mercury_conf.h.in:
Test for the sched_getcpu C function and utmpx.h header file, these are
used for thread pinning.
runtime/Mmakefile:
Include the mercury_threadscope.[hc] files in the list of runtime headers
and sources respectively.
While the CPU's clock speed is not always the speed that the CPU operates at,
it is the number of TSC units per second when the CPU supports the constant TSC
feature (see /proc/cpuinfo / CPUID). This change set is used in preparation for
upcoming work on exporting ThreadScope profiling data, see "Parallel
Performance Tuning for Haskell" - Don Jones Jr, Simon Marlow and Satnam Singh.
runtime/mercury_atomic_ops.c:
Retrieve the CPU frequency from the CPUID instruction and store it in
MR_cpu_cycles_per_sec
runtime/mercury_atomic_ops.h:
Export MR_cpu_cycles_per_sec
runtime/mercury_context.c:
Print the number of cycles per second in the parallel profiling data file
if we where able to detect it.
Made thread pinning off by default, the operating system should handle this
unless we have a good reason to.
configure.in:
Removed newly added declaration checking code.
doc/user_guide.texi:
Documentation corrections.
Adjusted the --pin-threads runtime option default.
runtime/mercury_atomic_ops.c
runtime/mercury_atomic_ops.h
Use __x86_64__ instead of __amd64__
Altered comments at the beginning of sections of the file to better
describe the contents of that section.
Placed comments at the end of long conditional compilation blocks that
match the condition at the beginning of the block.
runtime/mercury_conf.h.in:
Added editor hint for vim at the top of the file.
Remove newly added declarations section.
runtime/mercury_context.c:
Adjusted default behaviour of --pin-threads
Fixed some style issues.
runtime/mercury_context.h:
Fixed grammatical error.
runtime/mercury_wrapper.c:
Fixed grammatical error.
Fixed a missing break statement in a switch statement.
Improve the profiling of the parallel runtime code in two main ways:
+ Record data for more events.
+ Record high-precision timing data on x86 machines via the TSC where
access to the TSC is available.
Access to the TSC is available via two machine instructions. RDTSC - read
TSC. and RDTSCP - read TSC and processor ID. We prefer the latter as a
process migrated between two calls to RDTSC may cause an incorrect time
duration to be calculated (since TSC counts are seldom synchronized). We
fall back to RDTSC when RDTSCP is not available and gracefully record no
timing information when neither is available. Availability is detected via
the CPUID instruction, see MR_configure_profiling_timers().
runtime/mercury_context.c:
runtime/mercury_context.h:
Runtime profiling changes as above.
runtime/mercury_atomic_ops.c:
runtime/mercury_atomic_ops.h:
Add runtime profiling timing code.
Add new add and subtract atomic operations.
runtime/mercury_wrapper.c:
Call the new MR_configure_profiling_timers() procedure to detect the CPU
and configure access to the TSC.
Mmakefile:
runtime/Mmakefile:
'mmake tags' at the top level now builds the tags file for the runtime
directory.
The tags target in the runtime directory is now marked as PHONY so it is
generated even if it already exists.
Estimated hours taken: 3
Branches: main
Rename the runtime granularity control macros, variables and predicates.
Names of the runtime granularity control macros, variables and predicates are
now more descriptive and more consistent.
An alternative runtime granularity control predicate and macro is now
available, it considers the number of contexts and all sparks whereas the
original predicate and macro considers only the number of contexts and sparks
on the global queue.
A new predicate has been added to determine the number of worker threads that
the mercury runtime is configured to use.
library/par_builtin.m:
Renamed predicates.
Conform to changes in runtime/mercury_thread.h
Added the new predicates.
Removed some old foreign procedure attributes.
Addressed an XXX comment left by Zoltan.
runtime/mercury_context.c:
runtime/mercury_context.h:
Rename existing runtime granularity control variables and macros.
Add new runtime granularity control variable and macro.
runtime/mercury_wrapper.c:
runtime/mercury_wrapper.h:
Export MR_num_threads variable.
Make this variable an MR_Unsigned.
runtime/mercury_atomic_ops.c:
runtime/mercury_atomic_ops.h:
Introduce new atomic increment and decrement instructions. These are used
to count the number of local sparks created which is done outside of a
critical section.
library/Mmakefile:
Rebuild the par_builtin module when either runtime/mercury_context.h or
runtime/mercury_thread.h change.
compiler/granularity.m:
Conform to changes in runtime/mercury_context.h
Estimated hours taken: 0.2
Branches: main
Avoid problems with some versions of gcc when compiling the runtime atomic_ops
module at -O0 in non low-level .par grades.
runtime/mercury_atomic_ops.[hc]:
Implement MR_compare_and_swap_word using the builtin gcc compare
and swap if it is available. (In particular prefer this to the
handcoded assembler versions on x86 and x86_64.)
Only include the code in these modules if MR_LL_PARALLEL_CONJ
is defined. This helps to avoid problems with gcc in grades
where atomic operations are not used.
Branches: main
Make the parallel conjunction execution mechanism more efficient.
1. Don't allocate sync terms on the heap. Sync terms are now allocated in
the stack frame of the procedure call which originates a parallel
conjunction.
2. Don't allocate individual sparks on the heap. Sparks are now stored in
preallocated, growing arrays using an algorithm that doesn't use locks.
3. Don't have one mutex per sync term. Just use one mutex to protect
concurrent accesses to all sync terms (it's is rarely needed anyway). This
makes sync terms smaller and saves initialising a mutex for each parallel
conjunction encountered.
4. We don't bother to acquire the global sync term lock if we know a parallel
conjunction couldn't be executing in parallel. In a highly parallel program,
the majority of parallel conjunctions will be executed sequentially so
protecting the sync terms from concurrent accesses is unnecessary.
par_fib(39) is ~8.4 times faster (user time) on my laptop (Linux 2.6, x86_64),
which is ~3.5 as slow as sequential execution.
configure.in:
Update the configuration for a changed MR_SyncTerm structure.
compiler/llds.m:
Make the fork instruction take a second argument, which is the base
stack slot of the sync term.
Rename it to fork_new_child to match the macro name in the runtime.
compiler/par_conj_gen.m:
Change the generated code for parallel conjunctions to allocate sync
terms on the stack and to pass the sync term to fork_new_child.
compiler/dupelim.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_out.m:
compiler/llds_to_x86_64.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/reassign.m:
compiler/use_local_vars.m:
Conform to the change in the fork instruction.
compiler/liveness.m:
compiler/proc_gen.m:
Disable use of the parallel conjunction operator in the compiler as
older versions of the compiler will generate code incompatible with
the new runtime.
runtime/mercury_context.c:
runtime/mercury_context.h:
Remove the next pointer field from MR_Spark as it's no longer needed.
Remove the mutex from MR_SyncTerm. Add a field to record if a spark
belonging to the sync term was scheduled globally, i.e. if the
parallel conjunction might be executed in parallel.
Define MR_SparkDeque and MR_SparkArray.
Use MR_SparkDeques to hold per-context sparks and global sparks.
Change the abstract machine instructions MR_init_sync_term,
MR_fork_new_child, MR_join_and_continue as per the main change log.
Use a preprocessor macro MR_LL_PARALLEL_CONJ as a shorthand for
!MR_HIGHLEVEL_CODE && MR_THREAD_SAFE.
Take the opportunity to clean things up a bit.
runtime/mercury_wsdeque.c:
runtime/mercury_wsdeque.h:
New files containing an implementation of work-stealing deques. We
don't do work stealing yet but we use the underlying data structure.
runtime/mercury_atomic_ops.c:
runtime/mercury_atomic_ops.h:
New files to contain atomic operations. Currently it just contains
compare-and-swap for gcc/x86_64, gcc/x86 and gcc-4.1.
runtime/Mmakefile:
Add the new files.
runtime/mercury_engine.h:
runtime/mercury_mm_own_stacks.c:
runtime/mercury_wrapper.c:
Conform to runtime changes.
runtime/mercury_conf_param.h:
Update an outdated comment.