Looks like Valgrind has two tools that both do thread error detection: Helgrind and DRD. These tools are substantially similar.
My primary question is: when should I use one instead of the other to check my multi-threaded code?
More broadly, why are there two tools? I assume they aren't entirely redundant. What are the important differences? Should I generally plan on running my code through both tools?
While Helgrind can detect locking order violations, for most programs DRD needs less memory to perform its analysis. Also, DRD has support for detached threads. There are more subtle differences too - compare the respective manuals if you want to know more. See also http://valgrind.org/docs/manual/hg-manual.html and http://valgrind.org/docs/manual/drd-manual.html.
If you're using any POSIX synchronization primitives besides mutexes (e.g., semaphores, barriers, condition variables, etc.), DRD is worth a run -- it can identify some subtle misuses that Helgrind doesn't detect.
However, DRD seems to be much more resource intensive than Helgrind (in my runs using 3.14.0 there seems to be a tremendous amount of CPU overhead).
when should I use one instead of the other to check my multi-threaded code?
Depends on what you want to check that code for.
To check for data races, you might want to use ThreadSanitizer.
Comparison with DRD and others.
One other point to consider: as of valgrind version 3.6.0, DRD supports pthread spinlocks, but helgrind doesn't. I haven't tried 3.7.0, but the release notes lead me to believe that this hasn't changed.