diff --git a/stim/envi/binary.h b/stim/envi/binary.h index b4a66bf..13c9422 100644 --- a/stim/envi/binary.h +++ b/stim/envi/binary.h @@ -21,26 +21,31 @@ namespace stim{ /// minimizing the dependent parameter bps (bytes per second) class stream_optimizer{ protected: - size_t Bps; //bytes per second for the previous batch + size_t Bps[2]; //bytes per second for the previous batch size_t interval_B; //number of bytes processed this interval size_t interval_ms; //number of milliseconds spent in the current interval size_t n[2]; //current batch size (in bytes) + size_t h; //spacing used for finite difference calculations size_t dn; //delta value (in bytes) for setting the batch size (minimum change in batch parameter) size_t maxn; //maximum value for the batch size + double alpha; //alpha value controls the factor of the gradient that is used to calculate the next point (speed of convergence) + bool sample_step; //calculating the derivative (this class alternates between calculating dBps and B) bool forward_diff; //evaluate the derivative using forward differences size_t window_ms; //size of the interval (in milliseconds) integrated to get a reliable bps value // This function rounds x to the nearest value within dB - size_t round_limit(size_t n0){ - if(n0 > maxn) n0 = maxn; //limit the returned size of x to within the specified bounds - if(n0 < dn) n0 = dn; + size_t round_limit(double n0){ + if(n0 < 0) return dn; //if n0 is less than zero, return the lowest possible n + + size_t new_n = (size_t)(n0 + 0.5); //now n0 must be positive, so round it to the nearest integer + if(new_n > maxn) new_n = maxn; //limit the returned size of x to within the specified bounds - size_t lowest = n0 / dn; + size_t lowest = new_n / dn; size_t highest = lowest + dn; - size_t diff[2] = {n0 - lowest, highest - n0}; //calculate the two differences + size_t diff[2] = {new_n - lowest, highest - new_n}; //calculate the two differences if(diff[0] < diff[1]) return lowest; return highest; @@ -49,19 +54,79 @@ protected: public: //constructor initializes a stream optimizer - stream_optimizer(size_t current_batch_size, size_t min_batch_size, size_t max_batch_size, size_t window = 1000){ - Bps = 0; //initialize to zero bytes per second processed + stream_optimizer(size_t min_batch_size, size_t max_batch_size, double a = 0.0001, size_t window = 1000){ + //Bps = 0; //initialize to zero bytes per second processed + Bps[0] = Bps[1] = 0; //initialize the bits per second to 0 interval_B = 0; //zero bytes have been processed at initialization interval_ms = 0; //no time has been spent on the batch so far dn = min_batch_size; //set the minimum batch size as the minimum change in batch size maxn = max_batch_size; //set the maximum batch size - n[0] = current_batch_size; //set B + n[0] = max_batch_size; //set B + h = (max_batch_size / min_batch_size) / 10 * dn; + std::cout<<"h = "<::buffer_size/(double)1000000<<" MB"< rthread; std::future wthread; //create asynchronous threads for reading and writing - //readlines(src[0], 0, N[0]); //read the first batch into the 0 source buffer - //y_load += N[0]; //increment the loaded slice counter - //int b = 1; - std::chrono::high_resolution_clock::time_point t_start, pt_start; //high-resolution timers std::chrono::high_resolution_clock::time_point t_end, pt_end; size_t t_batch; //number of milliseconds to process a batch @@ -435,15 +438,15 @@ public: size_t data_rate; rt_total += readlines(src[0], 0, N[0]); //read the first batch into the 0 source buffer - y_load += N[0]; //increment the loaded slice counter - int b = 1; //initialize the double buffer to 0 + y_load += N[0]; //increment the loaded slice counter + int b = 1; //initialize the double buffer to 0 while(y_proc < Y()){ //while there are still slices to be processed t_start = std::chrono::high_resolution_clock::now(); //start the timer for this batch if(y_load < Y()){ //if there are still slices to be loaded, load them - if(y_proc > 0){ - N[b] = O.update(N[!b] * slice_bytes, t_batch, data_rate); //set the batch size based on optimization - std::cout<<"New N = "< 0){ + + + //} if(y_load + N[b] > Y()) N[b] = Y() - y_load; //if the next batch would process more than the total slices, adjust the batch size rthread = std::async(std::launch::async, &stim::bsq::readlines, this, src[b], y_load, N[b]); rt_total += rthread.get(); @@ -452,7 +455,6 @@ public: b = !b; //swap the double-buffer pt_total += binary::permute(dst[b], src[b], X(), N[b], Z(), 0, 2, 1); //permute the batch to a BIL file - //target.write((char*)dst[b], N[b] * slice_bytes); //write the permuted data to the output file wt_total += writeblock(&target, dst[b], N[b] * slice_bytes); //write the permuted data to the output file y_proc += N[b]; //increment the counter of processed pixels if(PROGRESS) progress = (double)( y_proc + 1 ) / Y() * 100; //increment the progress counter based on the number of processed pixels @@ -460,6 +462,8 @@ public: t_batch = std::chrono::duration_cast(t_end-t_start).count(); t_total += t_batch; //if(y_load < Y()) rt_total += rthread.get(); //if a new batch was set to load, make sure it loads after calculations + N[b] = O.update(N[!b] * slice_bytes, t_batch, data_rate); //set the batch size based on optimization + //std::cout<<"New N = "<