Commit f669bd29 authored by David Flynn's avatar David Flynn
Browse files

timing: report elapsed user time rather than wall time

This commit changes the application's reporting of elapsed time to
measure user time rather than wall time in order to reduce sources
of noise in evaluating runtime.

For output is now of the form:

  ```
  Processing time (wall): 123.456 s
  Processing time (user): 123.456 s
  ```



git-svn-id: http://wg11.sc29.org/svn/repos/MPEG-I/Part5-PointCloudCompression/TM/TMC3/trunk@1329 94298a81-5874-47c9-aab8-bfb24faeed7f
parent 33c5d884
......@@ -5,8 +5,12 @@ if (MSVC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:tbb.lib")
endif()
include(CheckSymbolExists)
check_symbol_exists(getrusage sys/resource.h HAVE_GETRUSAGE)
set (TMC3_VERSION_MAJOR 0)
set (TMC3_VERSION_MINOR 1)
configure_file (
"${CMAKE_CURRENT_SOURCE_DIR}/TMC3Config.h.in"
"${PROJECT_BINARY_DIR}/tmc3/TMC3Config.h"
......
......@@ -49,18 +49,28 @@ int main(int argc, char *argv[]) {
if (!ParseParameters(argc, argv, params)) {
return -1;
}
const auto start = std::chrono::high_resolution_clock::now();
// Timers to count elapsed wall/user time
pcc::chrono::Stopwatch<std::chrono::steady_clock> clock_wall;
pcc::chrono::Stopwatch<pcc::chrono::utime_inc_children_clock> clock_user;
clock_wall.start();
int ret = 0;
if (params.mode == CODEC_MODE_ENCODE || params.mode == CODEC_MODE_ENCODE_LOSSLESS_GEOMETRY) {
ret = Compress(params);
ret = Compress(params, clock_user);
} else {
ret = Decompress(params);
ret = Decompress(params, clock_user);
}
const auto end = std::chrono::high_resolution_clock::now();
std::cout << "Processing time: "
<< std::chrono::duration<double, std::milli>(end - start).count() / 1000.0 << " s"
<< std::endl;
clock_wall.stop();
using namespace std::chrono;
auto total_wall = duration_cast<milliseconds>(clock_wall.count()).count();
auto total_user = duration_cast<milliseconds>(clock_user.count()).count();
std::cout << "Processing time (wall): " << total_wall / 1000.0 << " s\n";
std::cout << "Processing time (user): " << total_user / 1000.0 << " s\n";
return ret;
}
......@@ -297,13 +307,15 @@ bool ParseParameters(int argc, char *argv[], Parameters &params) {
return true;
}
int Compress(const Parameters &params) {
int Compress(const Parameters &params, Stopwatch& clock) {
PCCPointSet3 pointCloud;
if (!pointCloud.read(params.uncompressedDataPath) || pointCloud.getPointCount() == 0) {
cout << "Error: can't open input file!" << endl;
return -1;
}
clock.start();
if (params.colorTransform == COLOR_TRANSFORM_RGB_TO_YCBCR) {
pointCloud.convertRGBToYUV();
}
......@@ -331,6 +343,8 @@ int Compress(const Parameters &params) {
return -1;
}
clock.stop();
assert(bitstream.size <= bitstream.capacity);
std::cout << "Total bitstream size " << bitstream.size << " B" << std::endl;
ofstream fout(params.compressedStreamPath, ios::binary);
......@@ -349,7 +363,7 @@ int Compress(const Parameters &params) {
return 0;
}
int Decompress(const Parameters &params) {
int Decompress(const Parameters &params, Stopwatch &clock) {
PCCBitstream bitstream = {};
ifstream fin(params.compressedStreamPath, ios::binary);
if (!fin.is_open()) {
......@@ -368,6 +382,8 @@ int Decompress(const Parameters &params) {
}
fin.close();
clock.start();
PCCTMC3Decoder3 decoder;
PCCPointSet3 pointCloud;
if (params.mode == CODEC_MODE_DECODE_LOSSLESS_GEOMETRY) { // read geometry from input file
......@@ -392,6 +408,8 @@ int Decompress(const Parameters &params) {
pointCloud.convertYUVToRGB();
}
clock.stop();
if (!pointCloud.write(params.reconstructedDataPath, true)) {
cout << "Error: can't open output file!" << endl;
return -1;
......
......@@ -56,6 +56,8 @@
#include "TMC3Config.h"
#include "pcc_chrono.h"
enum ColorTransform { COLOR_TRANSFORM_NONE = 0, COLOR_TRANSFORM_RGB_TO_YCBCR = 1 };
enum CodecMode {
......@@ -75,8 +77,10 @@ struct Parameters {
pcc::PCCTMC3Encoder3Parameters encodeParameters;
};
typedef pcc::chrono::Stopwatch<pcc::chrono::utime_inc_children_clock> Stopwatch;
bool ParseParameters(int argc, char *argv[], Parameters &params);
int Compress(const Parameters &params);
int Decompress(const Parameters &params);
int Compress(const Parameters &params, Stopwatch&);
int Decompress(const Parameters &params, Stopwatch&);
#endif /* TMC3_h */
#define TMC3_VERSION_MAJOR @TMC3_VERSION_MAJOR@
#define TMC3_VERSION_MINOR @TMC3_VERSION_MINOR@
/* Define to 1 if getrusage(2) is present */
#cmakedefine01 HAVE_GETRUSAGE
/* The copyright in this software is being made available under the BSD
* License, included below. This software may be subject to other third party
* and contributor rights, including patent rights, and no such rights are
* granted under this license.
*
* Copyright (c) 2018, ISO/IEC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the ISO/IEC nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#if _WIN32
# define _UNICODE
# include <windows.h>
#endif
#include "TMC3Config.h"
#include "pcc_chrono.h"
#if HAVE_GETRUSAGE
# include <sys/time.h>
# include <sys/resource.h>
#endif
//===========================================================================
#if _WIN32
namespace pcc {
namespace chrono {
namespace detail {
using hundredns = std::chrono::duration<int64_t, std::ratio<1, 10000000>>;
// global state to emulate getrusage(RUSAGE_CHILDREN).
hundredns g_cumulative_time_children {0};
}}}
#endif
//---------------------------------------------------------------------------
#if _WIN32
pcc::chrono::utime_inc_children_clock::time_point
pcc::chrono::utime_inc_children_clock::now() noexcept
{
HANDLE hProcess = GetCurrentProcess();
FILETIME dummy, userTime;
GetProcessTimes(hProcess, &dummy, &dummy, &dummy, &userTime);
ULARGE_INTEGER val;
val.LowPart = userTime.dwLowDateTime;
val.HighPart = userTime.dwHighDateTime;
using namespace detail;
using hundredns = std::chrono::duration<int64_t, std::ratio<1, 10000000>>;
return time_point(hundredns(val.QuadPart) + g_cumulative_time_children);
}
#endif
//---------------------------------------------------------------------------
#if HAVE_GETRUSAGE
pcc::chrono::utime_inc_children_clock::time_point
pcc::chrono::utime_inc_children_clock::now() noexcept
{
std::chrono::nanoseconds total;
struct rusage usage;
getrusage(RUSAGE_SELF, &usage);
total = std::chrono::seconds(usage.ru_utime.tv_sec)
+ std::chrono::microseconds(usage.ru_utime.tv_usec);
if (getrusage(RUSAGE_CHILDREN, &usage))
return time_point(total);
total += std::chrono::seconds(usage.ru_utime.tv_sec)
+ std::chrono::microseconds(usage.ru_utime.tv_usec);
return time_point(total);
}
#endif
//===========================================================================
/* The copyright in this software is being made available under the BSD
* License, included below. This software may be subject to other third party
* and contributor rights, including patent rights, and no such rights are
* granted under this license.
*
* Copyright (c) 2018, ISO/IEC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the ISO/IEC nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <chrono>
//===========================================================================
namespace pcc {
namespace chrono {
/**
* Clock reporting elapsed user time of the current process and children.
*
* NB: under winapi, only child processes that have completed execution
* via pcc::system() are reported.
*/
struct utime_inc_children_clock {
typedef std::chrono::nanoseconds duration;
typedef duration::rep rep;
typedef duration::period period;
typedef std::chrono::time_point<utime_inc_children_clock, duration> time_point;
static constexpr bool is_steady = true;
static time_point now() noexcept;
};
}}
//===========================================================================
namespace pcc {
namespace chrono {
/**
* Measurement of cumulative elapsed time intervals.
*
* This timer acts like a stopwatch and may be used to measure the
* cumulative periods between successive calls to start() and stop().
*/
template<typename Clock>
class Stopwatch {
public:
typedef typename Clock::duration duration;
/// Reset the accumulated interval count.
void reset();
/// Mark the beginning of a measurement period.
void start();
/// Mark the end of a measurement period.
///
/// @return the duration of the elapsed Clock time since start()
duration stop();
/// The sum of the previous elapsed time intervals.
///
/// NB: this excludes any currently active period marked by start().
///
/// @return cumulative elapsed time
constexpr duration count() const {
return cumulative_time_;
}
private:
typename Clock::time_point start_time_;
duration cumulative_time_ {0};
};
}}
//---------------------------------------------------------------------------
template<typename Clock>
void
pcc::chrono::Stopwatch<Clock>::reset() {
cumulative_time_ = cumulative_time_.zero();
}
//---------------------------------------------------------------------------
template<typename Clock>
void
pcc::chrono::Stopwatch<Clock>::start() {
start_time_ = Clock::now();
}
//---------------------------------------------------------------------------
template<typename Clock>
typename pcc::chrono::Stopwatch<Clock>::duration
pcc::chrono::Stopwatch<Clock>::stop() {
const auto& delta = duration(Clock::now() - start_time_);
cumulative_time_ += delta;
return delta;
}
//===========================================================================
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment