Skip to content

Latest commit

 

History

History
288 lines (243 loc) · 8 KB

README.md

File metadata and controls

288 lines (243 loc) · 8 KB

Seer

Branch Status
Master Master
Develop Develop

A single header performance logger outputting to chrome tracing in C++11 for windows, linux and mac, readable using chrome://tracing

Example when loaded in chrome://tracing Image

Example code

Install:

Drop Seer.hpp in to your include path and you should be good to go.

Functions:

Getting output and memory usage:

Speed:

Tests:


Functions:

ScopeTimer:

ScopeTimer will measure the time spent in a block/scope.

{
    seer::ScopeTimer("test"); // This will measure 2 seconds.
    std::this_thread::sleep_for(2s);
}

Image

Timer:

If ScopeTimer can not be used, or more manual control over the end time is required Timer will measure the time from object creation to end member call.

{
	seer::Timer test("test");
	std::this_thread::sleep_for(2s);
	test.end();
}

Image

Async:

Async allows you to draw visual connections between scopes timers, this shows up in chrome as arrows joining blocks. This is handy for tracking events across threads or separated by time.

Across Threads:

seer::Async async;	
{
	const auto timer = async.create_timer("Step 1");
	std::this_thread::sleep_for(std::chrono::seconds(1));
}
	
std::async(std::launch::async, [async] {
	const auto timer2 = async.create_timer("Step 2");
	std::this_thread::sleep_for(std::chrono::seconds(1));
}).get();
	
{
	const auto timer3 = async.create_timer("Step 3");
	std::this_thread::sleep_for(std::chrono::seconds(1));
}

Image

Across time:

seer::Async async;	
{
	const auto timer = async.create_timer("Step 1");
	std::this_thread::sleep_for(std::chrono::seconds(1));
}
	// some other work
{
	const auto timer2 = async.create_timer("Step 2");
	std::this_thread::sleep_for(std::chrono::seconds(1));	
}
	// some more work
{
	const auto timer3 = async.create_timer("Step 3");
	std::this_thread::sleep_for(std::chrono::seconds(1));
}

Image

Counter:

Counter can be used for tracking a value over time.

Note: multiple counters sharing the same name will appear in the same chrome trace.

{
    seer::Counter<int> counter("test", 1);
    std::this_thread::sleep_for(2s);
    counter.update(2);
}

Image

instant_event:

Will place an instant event scoped to either process (default), thread, globally.

{
	seer::instant_event("test"); // process
	seer::instant_event("test", seer::InstantEventScope::thread); // process
	seer::instant_event("test", seer::InstantEventScope::global); // global
}

Thread:

Image

Process:

Image

Global:

Image

mark:

Will produce a mark.

{
	seer::mark("test");
}

Image

set_thread_name:

Will name the current thread or optional with another threads id.

{
	seer::set_thread_name("render");
	seer::set_thread_name("worker", worker.id);
}

set_process_name:

Will name the current process.

{
	seer::set_process_name("my amazing app"); // this can be called at any point in time
}

Image


Getting output and memory usage:

output:

chrome://tracing expects a json file, this can be fetched in several way.

Interface to this data can be found through seer::buffer

{
	seer::buffer.dump_to_file("my profile data.json"); //defaults to "profile.json"
	file << seer::buffer; //by stream
	std::string json = seer::buffer.str(); //by string
}

buffer and memory usage:

Internally Seer allocates a buffer of memory to write to, this defaults to ~10mb. Monitoring and changes to this buffer can be found through seer::buffer

{
	// usage
	seer::buffer.usage().usage_in_bytes;
	seer::buffer.usage().total_in_bytes;
	seer::buffer.usage().percent_used;
	
	// resize
	seer::buffer.resize(1000000000); // resize to 1gb

	// clear
	seer::buffer.clear();
}

buffer filled behaviour:

When the internal buffer fills up by default it resets and starts a fresh, chucking out its old data, however this can be customised

{	
	seer::buffer_overflow_behaviour = seer::BufferOverflowBehaviour::reset;
	// the default, the buffer forgets its old data and starts again

	seer::buffer_overflow_behaviour = seer::BufferOverflowBehaviour::expand;
	// the buffer will grow on its own with no upper limit

	seer::buffer_overflow_behaviour = seer::BufferOverflowBehaviour::discard;
	// the buffer will discard all new events once it fills
}

Speed:

benchmarks:

While seer may be header only, these benchmarks use google benchmark and require building.

Dependencies (included in the repo):

Mac and linux:

git clone https://github.com/ThomasMonkman/Seer.git
cd ./Seer
mkdir build && cd build/
cmake -DCMAKE_BUILD_TYPE=Release ../
make
benchmarks/seer_benchmark

Windows:

Simply open the repo in visual studio 17, and with its new cmake features and you should just be able to run the projects, make sure you use release.

Test:

test:

While seer may be header only, these tests use catch 2 and require building.

Dependencies (included in the repo):

Mac and linux:

git clone https://github.com/ThomasMonkman/Seer.git
cd ./Seer
mkdir build && cd build/
cmake -DCMAKE_BUILD_TYPE=Release ../
make
tests/seer_unit

Windows:

Simply open the repo in visual studio 17, and with its new cmake features and you should just be able to run the projects.

Example code:

{
	seer::set_process_name("my amazing app");
	seer::set_thread_name("render");
	seer::instant_event("frame start", seer::InstantEventScope::process);
	seer::Counter<int> temperature("temperature", 0);
	seer::Async async;
	seer::ScopeTimer frame("frame");
	std::this_thread::sleep_for(std::chrono::seconds(1));
	temperature.update(2);
	{
		seer::ScopeTimer input("get input");
		std::this_thread::sleep_for(std::chrono::milliseconds(250));
		temperature.update(5);
		seer::instant_event("key press", seer::InstantEventScope::thread);
		test_helper::get_with_timeout<void>(std::async(std::launch::async, [async, &temperature] {
			seer::set_thread_name("input");
			const auto timer = async.create_timer("capture keypress");
			std::this_thread::sleep_for(std::chrono::seconds(1));
			temperature.update(1);
		}));
		std::this_thread::sleep_for(std::chrono::milliseconds(250));
		temperature.update(10);
		const auto timer = async.create_timer("process keypress");
		std::this_thread::sleep_for(std::chrono::milliseconds(250));
		seer::mark("done");
	}
	temperature.update(4);
	std::this_thread::sleep_for(std::chrono::milliseconds(250));
	seer::instant_event("sun outside", seer::InstantEventScope::global);

}
seer::buffer.dump_to_file("full-showcase.json");