 		M1[tid * 3 + 1] = green;
 		M1[tid * 3 + 2] = red;
 
+		M2[tid * 3]     = 0;
+		M2[tid * 3 + 1] = 0;
+		M2[tid * 3 + 2] = 0;
+
 		// Initialize pixel count
-		n[tid * 3]     = 1;
-		n[tid * 3 + 1] = 1;
-		n[tid * 3 + 2] = 1;
+		n[tid] = 1;
 	}
 	else
 	{
-		// This thread has nothing to contribute
+		// This thread is outside the bounds of the
+		// image and therefore has nothing to contribute
 		// to the final result
-		n[tid * 3]     = 0;
-		n[tid * 3 + 1] = 0;
-		n[tid * 3 + 2] = 0;
-	}
-
-	M2[tid * 3]     = 0;
-	M2[tid * 3 + 1] = 0;
-	M2[tid * 3 + 2] = 0;
+		n[tid] = 0;
+	}
 	
     __syncthreads();
 

	{
		// M1 is the mean already - nothing extra needed
		// calculate stddev from M2 and n
		M2[tid] = sqrt(M2[tid] / n[tid]);
	}
	__syncthreads();


	// with just one final result per block
    for (unsigned int s = (blockDim.x * blockDim.y) / 2; s > 0; s >>= 1)
    {
        if ((tid < s) && (n[tid + s]))
		{
			// N is the same for all 3 channels of a
			// given pixel. Re-use it when combining
			// the stats of the 3 channels
			unsigned int saved_n = n[tid];
			for (int i = 0; i < 3; i++)
			{
				// Blue, green, red = 3 entries per shared mem array
				const int i1 = 3 * tid + i;
				const int i2 = 3 * (tid + s) + i;
				n[tid] = saved_n;
				combine_running_totals(M1[i1], M1[i2], M2[i1], M2[i2], n[tid], n[tid + s]);
			}
			// Setting n = 0 for the thread just copied out
			// of will prevent the data from being added
			// a second time
			n[tid + s] = 0;
        }
        __syncthreads();
    }
