public:
Timer();
virtual ~Timer();
- void Start();
- void Stop();
- float MilliSeconds();
- float MicroSeconds();
- float Seconds();
+ virtual void Start();
+ virtual void Stop();
+ virtual float MilliSeconds();
+ virtual float MicroSeconds();
+ virtual float Seconds();
inline bool initted() { return initted_; }
inline bool running() { return running_; }
float elapsed_microseconds_;
};
+class CPUTimer : public Timer {
+ public:
+ explicit CPUTimer();
+ virtual ~CPUTimer() {}
+ virtual void Start();
+ virtual void Stop();
+ virtual float MilliSeconds();
+ virtual float MicroSeconds();
+};
+
} // namespace caffe
#endif // CAFFE_UTIL_BENCHMARK_H_
// This function is used to create a thread that prefetches the data.
template <typename Dtype>
void DataLayer<Dtype>::InternalThreadEntry() {
- Timer batch_timer;
+ CPUTimer batch_timer;
batch_timer.Start();
- float read_time = 0;
- float trans_time = 0;
- Timer timer;
+ double read_time = 0;
+ double trans_time = 0;
+ CPUTimer timer;
CHECK(this->prefetch_data_.count());
CHECK(this->transformed_data_.count());
Dtype* top_data = this->prefetch_data_.mutable_cpu_data();
if (datum.encoded()) {
cv_img = DecodeDatumToCVMat(datum);
}
- read_time += timer.MilliSeconds();
+ read_time += timer.MicroSeconds();
timer.Start();
// Apply data transformations (mirror, scale, crop...)
if (this->output_labels_) {
top_label[item_id] = datum.label();
}
- trans_time += timer.MilliSeconds();
+ trans_time += timer.MicroSeconds();
// go to the next iter
++iter_;
if (iter_ == dataset_->end()) {
}
}
batch_timer.Stop();
- DLOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << "ms.";
- DLOG(INFO) << "Read time: " << read_time << "ms.";
- DLOG(INFO) << "Transform time: " << trans_time << "ms.";
+ DLOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << " ms.";
+ DLOG(INFO) << " Read time: " << read_time / 1000 << " ms.";
+ DLOG(INFO) << "Transform time: " << trans_time / 1000 << " ms.";
}
INSTANTIATE_CLASS(DataLayer);
// This function is used to create a thread that prefetches the data.
template <typename Dtype>
void ImageDataLayer<Dtype>::InternalThreadEntry() {
- Timer batch_timer;
+ CPUTimer batch_timer;
batch_timer.Start();
- float read_time = 0;
- float trans_time = 0;
- Timer timer;
+ double read_time = 0;
+ double trans_time = 0;
+ CPUTimer timer;
CHECK(this->prefetch_data_.count());
CHECK(this->transformed_data_.count());
Dtype* top_data = this->prefetch_data_.mutable_cpu_data();
if (!cv_img.data) {
continue;
}
- read_time += timer.MilliSeconds();
+ read_time += timer.MicroSeconds();
timer.Start();
// Apply transformations (mirror, crop...) to the image
int offset = this->prefetch_data_.offset(item_id);
this->transformed_data_.set_cpu_data(top_data + offset);
this->data_transformer_.Transform(cv_img, &(this->transformed_data_));
- trans_time += timer.MilliSeconds();
+ trans_time += timer.MicroSeconds();
top_label[item_id] = lines_[lines_id_].second;
// go to the next iter
}
}
batch_timer.Stop();
- DLOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << "ms.";
- DLOG(INFO) << "Read time: " << read_time << "ms.";
- DLOG(INFO) << "Transform time: " << trans_time << "ms.";
+ DLOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << " ms.";
+ DLOG(INFO) << " Read time: " << read_time / 1000 << " ms.";
+ DLOG(INFO) << "Transform time: " << trans_time / 1000 << " ms.";
}
INSTANTIATE_CLASS(ImageDataLayer);
void WindowDataLayer<Dtype>::InternalThreadEntry() {
// At each iteration, sample N windows where N*p are foreground (object)
// windows and N*(1-p) are background (non-object) windows
- Timer batch_timer;
+ CPUTimer batch_timer;
batch_timer.Start();
- float read_time = 0;
- float trans_time = 0;
- Timer timer;
+ double read_time = 0;
+ double trans_time = 0;
+ CPUTimer timer;
Dtype* top_data = this->prefetch_data_.mutable_cpu_data();
Dtype* top_label = this->prefetch_label_.mutable_cpu_data();
const Dtype scale = this->layer_param_.window_data_param().scale();
return;
}
}
- read_time += timer.MilliSeconds();
+ read_time += timer.MicroSeconds();
timer.Start();
const int channels = cv_img.channels();
}
}
}
- trans_time += timer.MilliSeconds();
+ trans_time += timer.MicroSeconds();
// get window label
top_label[item_id] = window[WindowDataLayer<Dtype>::LABEL];
}
}
batch_timer.Stop();
- DLOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << "ms.";
- DLOG(INFO) << "Read time: " << read_time << "ms.";
- DLOG(INFO) << "Transform time: " << trans_time << "ms.";
+ DLOG(INFO) << "Prefetch batch: " << batch_timer.MilliSeconds() << " ms.";
+ DLOG(INFO) << " Read time: " << read_time / 1000 << " ms.";
+ DLOG(INFO) << "Transform time: " << trans_time / 1000 << " ms.";
}
INSTANTIATE_CLASS(WindowDataLayer);
CUDA_CHECK(cudaEventElapsedTime(&elapsed_milliseconds_, start_gpu_,
stop_gpu_));
// Cuda only measure milliseconds
- elapsed_microseconds_ = elapsed_milliseconds_ / 1000;
+ elapsed_microseconds_ = elapsed_milliseconds_ * 1000;
#else
NO_GPU;
#endif
}
}
+CPUTimer::CPUTimer() {
+ this->initted_ = true;
+ this->running_ = false;
+ this->has_run_at_least_once_ = false;
+}
+
+void CPUTimer::Start() {
+ if (!running()) {
+ this->start_cpu_ = boost::posix_time::microsec_clock::local_time();
+ this->running_ = true;
+ this->has_run_at_least_once_ = true;
+ }
+}
+
+void CPUTimer::Stop() {
+ if (running()) {
+ this->stop_cpu_ = boost::posix_time::microsec_clock::local_time();
+ this->running_ = false;
+ }
+}
+
+float CPUTimer::MilliSeconds() {
+ if (!has_run_at_least_once()) {
+ LOG(WARNING) << "Timer has never been run before reading time.";
+ return 0;
+ }
+ if (running()) {
+ Stop();
+ }
+ this->elapsed_milliseconds_ = (this->stop_cpu_ -
+ this->start_cpu_).total_milliseconds();
+ return this->elapsed_milliseconds_;
+}
+
+float CPUTimer::MicroSeconds() {
+ if (!has_run_at_least_once()) {
+ LOG(WARNING) << "Timer has never been run before reading time.";
+ return 0;
+ }
+ if (running()) {
+ Stop();
+ }
+ this->elapsed_microseconds_ = (this->stop_cpu_ -
+ this->start_cpu_).total_microseconds();
+ return this->elapsed_microseconds_;
+}
+
} // namespace caffe
Timer forward_timer;
Timer backward_timer;
Timer timer;
- std::vector<float> forward_time_per_layer(layers.size(), 0.0);
- std::vector<float> backward_time_per_layer(layers.size(), 0.0);
- float forward_time = 0.0;
- float backward_time = 0.0;
+ std::vector<double> forward_time_per_layer(layers.size(), 0.0);
+ std::vector<double> backward_time_per_layer(layers.size(), 0.0);
+ double forward_time = 0.0;
+ double backward_time = 0.0;
for (int j = 0; j < FLAGS_iterations; ++j) {
Timer iter_timer;
iter_timer.Start();
// so that we will notice Reshape performance bugs.
layers[i]->Reshape(bottom_vecs[i], top_vecs[i]);
layers[i]->Forward(bottom_vecs[i], top_vecs[i]);
- forward_time_per_layer[i] += timer.MilliSeconds();
+ forward_time_per_layer[i] += timer.MicroSeconds();
}
- forward_time += forward_timer.MilliSeconds();
+ forward_time += forward_timer.MicroSeconds();
backward_timer.Start();
for (int i = layers.size() - 1; i >= 0; --i) {
timer.Start();
layers[i]->Backward(top_vecs[i], bottom_need_backward[i],
bottom_vecs[i]);
- backward_time_per_layer[i] += timer.MilliSeconds();
+ backward_time_per_layer[i] += timer.MicroSeconds();
}
- backward_time += backward_timer.MilliSeconds();
+ backward_time += backward_timer.MicroSeconds();
LOG(INFO) << "Iteration: " << j + 1 << " forward-backward time: "
- << iter_timer.MilliSeconds() << " milliseconds.";
+ << iter_timer.MilliSeconds() << " ms.";
}
+ LOG(INFO) << "Average time per layer: ";
for (int i = 0; i < layers.size(); ++i) {
const caffe::string& layername = layers[i]->layer_param().name();
LOG(INFO) << std::setfill(' ') << std::setw(10) << layername <<
- "\tforward: " << forward_time_per_layer[i] << " milliseconds.";
+ "\tforward: " << forward_time_per_layer[i] / 1000 /
+ FLAGS_iterations << " ms.";
LOG(INFO) << std::setfill(' ') << std::setw(10) << layername <<
- "\tbackward: " << backward_time_per_layer[i] << " milliseconds.";
+ "\tbackward: " << backward_time_per_layer[i] / 1000 /
+ FLAGS_iterations << " ms.";
}
- LOG(INFO) << "Forward pass: " << forward_time <<
- " milliseconds.";
- LOG(INFO) << "Backward pass: " << backward_time <<
- " milliseconds.";
- LOG(INFO) << "Total Time: " << total_timer.MilliSeconds() <<
- " milliseconds.";
+ total_timer.Stop();
+ LOG(INFO) << "Average Forward pass: " << forward_time / 1000 /
+ FLAGS_iterations << " ms.";
+ LOG(INFO) << "Average Backward pass: " << backward_time / 1000 /
+ FLAGS_iterations << " ms.";
+ LOG(INFO) << "Average Forward-Backward: " << total_timer.MilliSeconds() /
+ FLAGS_iterations << " ms.";
+ LOG(INFO) << "Total Time: " << total_timer.MilliSeconds() << " ms.";
LOG(INFO) << "*** Benchmark ends ***";
return 0;
}
#include <algorithm>
#include <string>
+#include <utility>
+#include <vector>
#include "caffe/dataset_factory.hpp"
#include "caffe/proto/caffe.pb.h"