Skip to content

Commit

Permalink
new option --rand, randomize task prerequisites. Suggested by Thomas …
Browse files Browse the repository at this point in the history
…Sawyer.
  • Loading branch information
quix committed Sep 13, 2008
1 parent 2bc1ab0 commit 374f864
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 3 deletions.
36 changes: 36 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,42 @@ other tasks is rather contrary to this notion, throwing a monkey
wrench into the system. An exception will be raised when this is
attempted in multi-threaded mode.

=== Migrating to -j

First of all, do you want to bother with <tt>-j</tt>? If you are
satisfied with your build time, then there is really no reason to use
it.

If on the other hand your build takes twenty minutes to complete, you
may be interested in investing some time getting the full dependency
tree correct in order to take advantage of multiple CPUs or cores.

Though is no way for Drake to fathom what <em>you</em> mean by a
correct dependency, there is a tool available which helps you get
closer to saying what you mean.

% drake --rand[=SEED]

This will randomize the order in which prerequisites are invoked.
When given the optional SEED integer, it will call srand(SEED) to
produce the same permutation each time.

Though this may produce an error due to an unspecified dependency, at
least it will be an error which is exactly the same on each run. In
addition, you'll have the major debugging advantage of using a single
thread.

The randomize option will also work in multi-threaded mode. After
all, once <tt>-jN</tt> is running smoothly there is <em>still</em> no
guarantee that you have it right. However with each successful
execution of <tt>-jN --rand</tt>, the probability of correctness gets
closer to 1 (though asymptotically so).

(The only way to <em>prove</em> correctness is to test <em>all</em>
such permutations, which for any non-trivial project would be
prohibitively large, especially those which meaningfully benefit from
<tt>-j</tt>.)

== Links

* Download: http://rubyforge.org/frs/?group_id=6530
Expand Down
18 changes: 15 additions & 3 deletions lib/rake.rb
Original file line number Diff line number Diff line change
Expand Up @@ -595,13 +595,19 @@ def invoke_with_call_chain(task_args, invocation_chain) # :nodoc:
end
return if @already_invoked
@already_invoked = true

if application.options.randomize
@prerequisites = @prerequisites.sort_by { rand }
end

prereqs =
if application.num_threads == 1
invoke_prerequisites(task_args, new_chain)
nil
else
invoke_prerequisites_parallel(task_args, new_chain)
end

if needed?
if application.num_threads == 1
execute(task_args)
Expand Down Expand Up @@ -2276,9 +2282,15 @@ def standard_rake_options
['--threads', '-j N', "Specifies the number of threads to run simultaneously.",
lambda { |value| self.num_threads = value.to_i }
],
#['--fork', '-k', "When --threads=N given, run each thread in a separate process.",
# lambda { options.fork = true }
#],
['--rand[=SEED]', "Randomize task prerequisite orders",
lambda { |value|
MultiTask.class_eval { remove_method(:invoke_prerequisites) }
options.randomize = true
if value
srand(value.to_i)
end
}
],
['--libdir', '-I LIBDIR', "Include LIBDIR in the search path for required modules.",
lambda { |value| $:.push(value) }
],
Expand Down

0 comments on commit 374f864

Please sign in to comment.