lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Parallel blues


From: Greg Chicares
Subject: Re: [lmi] Parallel blues
Date: Tue, 20 Jun 2017 16:01:08 +0000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0

On 2016-07-18 19:55, Vadim Zeitlin wrote:
> 
>  So I tried to parallelize test_coding_rules. As expected, doing it turned
> out to be very simple and it took me about 30 minutes to write the code

I'd like to do something about calendar_date_test, because it takes
eleven seconds to run, while no other i686 lmi unit test takes more
than six seconds...and, since I run them in parallel, if I could run
this one test in half the time, then I could run the whole unit-test
suite in half the time. I'm considering two approaches, and it seems
like one must be far better than the other, but I'm not sure which
is which, and hope you have a clearer opinion than I.

(1) Parallelize it. TestBirthdateLimitsExhaustively() is called three
times, with different arguments, and each of those three runs takes
two and a half seconds, so it seems natural to run each in its own
thread. This would be my first attempt at writing multithreaded code
myself, so it has great educational value. However, I'd be running
sixty-three unit tests via parallel make, of which one would be
running in parallel via multithreading, and is that combination
somehow unholy?

(2) Split calendar_date_test into several separate tests, and let
make handle all the parallelism. This wouldn't be educational, but
I'd be more likely to get it right the first time, with less effort.
However, it seems unnatural to split a unit test into pieces.

Is one way clearly better?

As for the first option (multithreading), the notes in your original
post are helpful:

>  First of them, already seen with MSVC build, is that even though I used a
> mutex to serialize the error messages logged to standard output and error
> streams, the relative order of these messages is not defined any more and
> so test_coding_rules.sh is broken by this change.

GNU make's '--output-sync' takes care of that automatically, which
may be a reason to prefer option (2) in general. But it doesn't
matter for TestBirthdateLimitsExhaustively(), which is expected to
produce no output: all its tests should always pass.

(BTW, the reason why that function takes so long is that it performs
an exhaustive test of a function that is implemented iteratively.
Synopsis: for an extensible set of age-determination rules:
  - the customary convention: "what age are you today?"
  - "what age are you on your birthday closest to today?"
    - resolving the equidistant case upward; and, alternatively,
    - resolving the equidistant case downward
  ...and other rules that are even more unnatural...
determine the {lowest, highest} birthdates that would be consistent
with your being age {0, 1, 2, 3, 4} today, for every calendar date
in [1999-12-31, 2005-01-01] so that every possible number of
leap-year days occurs in the applicable period. It's possible to
do this analytically for a small finite set of age-determination
rules, but if more rules are added, it's pretty daunting to figure
out the date arithmetic; but, most importantly, it's infeasibly
hard to make sure the test is correct. That's why we simply state
the conditions for validity without trying to specify an algorithm
that returns the desired answer directly.)

>  What was really bad is that I discovered that the compiler we use doesn't
> support C++11 thread library *at all*.

[...i.e., if msw threads are used; however...]

>  So to use the code I've written we would need to switch to using the POSIX
> threads version and also distribute the POSIX threads emulation library
> libwinpthread-1.dll used by it to implement its (inefficient, but better
> than nothing) implementation of C++11 threading.

We already have to distribute libgcc and libstdc++ DLLs, and in order
to support both 32- and 64-bit builds (even for just a month or two
during migration to a 64-bit world) I'm going to have to make sure I
put the right ones on $PATH. The problem doesn't become harder with
three DLLs than with two.

> Obviously, changing the
> compiler -- again -- is not a step to be undertaken lightly,

[...yet we do plan to take that step, before too long I hope...]

> so I've looked
> for possible alternatives. And, interestingly enough, I did find one at
> https://github.com/meganz/mingw-std-threads. As explained there, this
> provides a simple header-only implementation of C++11 threading reusing
> some of the classes provided by libstdc++. This is clearly a hack

I glanced at it and concur. I'd rather change the compiler, because
we want to do that anyway; and picking a different threading model
shouldn't matter because we aren't using threads in production.

>  For completeness, I'd also like to mention that the decision to not go
> with TDM-GCC seems more and more regrettable retroactively

[...for a whole host of snipped reasons; however...]

>  The main problem with TDM-GCC is, of course, that Debian doesn't provide a
> cross-compiler based on it.

That's a compelling reason not to use TDM. And if TDM ever stops updating,
I doubt anyone will undertake to maintain it, whereas redhat probably
wouldn't let MinGW-w64 disappear.

> And, at least in this case, it's really nice to
> use Debian packages because they provide both Win32 and POSIX threading
> versions of MinGW-w64 and switching from the former (default) to the latter
> was as simple as
> 
>       # update-alternatives --set i686-w64-mingw32-g++ 
> /usr/bin/i686-w64-mingw32-g++-posix

Very handy.

> (of course, specifying compiler on the configure command line explicitly
> would have worked as well). But except for this, and if we do decide to
> switch the compiler again, TDM-GCC really seems like a much more reasonable
> alternative.

OTOH, AIUI, TDM provides native msw binaries, whereas the debian packages
are ELF binaries that don't bring in the fragility and overhead of wine.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]