 
         sminval[tid] = mymin;
         smaxval[tid] = mymax;
-
         __syncthreads();
 
-        if (nthreads >= 512) if (tid < 256) { merge(tid, 256, sminval, smaxval); __syncthreads(); }
-        if (nthreads >= 256) if (tid < 128) { merge(tid, 128, sminval, smaxval); __syncthreads(); }
-        if (nthreads >= 128) if (tid < 64) { merge(tid, 64, sminval, smaxval); __syncthreads(); }
-
-        if (tid < 32)
-        {
-            if (nthreads >= 64) merge(tid, 32, sminval, smaxval);
-            if (nthreads >= 32) merge(tid, 16, sminval, smaxval);
-            if (nthreads >= 16) merge(tid, 8, sminval, smaxval);
-            if (nthreads >= 8) merge(tid, 4, sminval, smaxval);
-            if (nthreads >= 4) merge(tid, 2, sminval, smaxval);
-            if (nthreads >= 2) merge(tid, 1, sminval, smaxval);
-        }
+        find_min_max_in_smem<nthreads, best_type>(sminval, smaxval, tid);
 
         if (tid == 0) 
         {



    template <int size, typename T>
    __device__ void sum_shared_mem(volatile T* data, const unsigned int tid)
    {
        T sum = data[tid];

        if (size >= 512) if (tid < 256) { data[tid] = sum = sum + data[tid + 256]; } __syncthreads();
        if (size >= 256) if (tid < 128) { data[tid] = sum = sum + data[tid + 128]; } __syncthreads();
        if (size >= 128) if (tid < 64) { data[tid] = sum = sum + data[tid + 64]; } __syncthreads();

        if (tid < 32)
        {

    }


    template <int size, typename T>
    __device__ void find_min_max_in_smem(volatile T* minval, volatile T* maxval, const unsigned int tid)
    {
        if (size >= 512) { if (tid < 256) { merge(tid, 256, minval, maxval); } __syncthreads(); }
        if (size >= 256) { if (tid < 128) { merge(tid, 128, minval, maxval); }  __syncthreads(); }
        if (size >= 128) { if (tid < 64) { merge(tid, 64, minval, maxval); } __syncthreads(); }

        if (tid < 32)
        {
            if (size >= 64) merge(tid, 32, minval, maxval);
            if (size >= 32) merge(tid, 16, minval, maxval);
            if (size >= 16) merge(tid, 8, minval, maxval);
            if (size >= 8) merge(tid, 4, minval, maxval);
            if (size >= 4) merge(tid, 2, minval, maxval);
            if (size >= 2) merge(tid, 1, minval, maxval);
        }
    }


    template <int nthreads, typename T>
    __global__ void min_max_kernel(const DevMem2D src, T* minval, T* maxval)
    {
