Adds parellized introsort, improves benchmarking

I made a very basic parallelized version of introsort to investigate
multithreading as an optimization. It appears that for large arrays, the
speedup gained by processing chunks of the array in parallel outweigh
the overhead of threading, but for small arrays, the multithreaded
implementation underperforms compared to normal introsort. That said,
parallelization is done by simply dividing into 12 subarrays, regardless
of input size. There seems to be some sort of critical point at which
threading is the more successful strategy, which benchmarking will
hopefully reveal. Also, a more flexible threading scheme (i.e. different
chunk number based on input size) may help. Additionally, I need to
implement mergesort and timsort, but in order to test whether or not
multithreading can be a successful strategy, I've just used an external
library for timsort as a temporary stand-in.

Also adds a more generic benchmarking function for arrays of generic
types which calculates mean elements per microsecond as well as the
standard deviation across all samples. However, in part because it takes
a function pointer argument, there doesn't appear to be a way to operate
generically on arrays and STL containers (pointers are random-access
iterators, STL containers are not) from a single benchmarking function
template. The other issue is the difference in memory management
stategies, which is also reflected in the data-generating methods.