It's pretty easy, really.
DMB - blocks all subsequent memory accesses until preceding memory accesses have finished. Non memory accessing instructions may continue.
DSB - blocks /all/ instructions until preceding memory accesses have finished.
ISB - flushes instruction caches (you need this one if you're doing self-modifying code)
Cache flush - flushes data cache.
So you use dmb when you want to be sure preceding memory accesses have finished, but continue doing other stuff (for example, setting a semaphore), dsb when you need everything to be finished before doing anything else (signalling other processes), isb when you've been messing with instructions, and cache flushing when memory is changing under the processor's feet.
http://infocenter.arm.com/help/topic/co ... ok_A08.pdf
is a reasonable read, although aimed at cortex-a processors the concepts remain correct.