Internal Profiling

Profiling API

The cohtml::System exposes a profiling API that can be used in Development builds of Prysm.

Overview

The method cohtml::System::EnableProfling can be used to start and stop the emitting of internal profiling markers. The profiling markers can be used to better understand what Prysm is doing and where its processing time is spent. For more in depth explanation of what happens internally in Prysm, see the profiling and optimization guide. In there we give an overview of what profiling markers there are and what they show.

Different platforms use different profiling markers.

  • on PS4/PS5/Xbox One/Xbox Series X/S - Prysm uses the platform native profiling markers
  • on other platforms like Desktop, Mobile, and Nintendo Switch - Prysm uses minitrace to emit events that are written to a JSON file and then can be inspected in tools like Chrome’s chrome://tracing/ tab or Perfetto

Example of Minitrace performance recording visualized in Chrome through chrome://tracing/:

How to use

cohtml::System::EnableProfling accepts a file path as an argument. The file path will be used when profiling through minitrace and Prysm will create a JSON file that will contain all profiling messages. For example, to illustrate the profiling on Windows:

The level argument of cohtml::System::EnableProfling gives the client code to select a profiling level that affects how much profiling markers Prysm will emit:

  • 'level=1 - only basic markers are emitted. This can be used for high-level performance investigation of major Prysm’s systems
  • 'level=2 - enables all profiling markers. This can negatively impact performance but provides a lot more information for low-level investigations.

The basic usage of the new API goes as follows:

// example implementation of the cohtml::ISyncStreamWriter interace. This implementation
// can be used as guideline if the default internal "cohtml::ISyncStreamWriter"
// is undesirable.
class FileWriter : public cohtml::ISyncStreamWriter
{
public:
	FileWriter(const char* path)
	{
		m_File.open(path, std::ofstream::out | std::ofstream::binary);
	}

	virtual void Write(const char* data, unsigned count) override
	{
		if (m_File.is_open())
		{
			m_File.write(data, count);
		}
	}

	virtual void Close() override
	{
		if (m_File.is_open())
		{
			m_File.close();
		}

		delete this;
	}

	bool IsOpen()
	{
		return m_File.is_open();
	}

private:
	std::ofstream m_File;
};

// Example implementation of the cohtml::IFileSystemWriter. This implementation
// can be used as guideline if the default internal "cohtml::IFileSystemWriter"
// is undesirable.
class FileSystemWriter : public cohtml::IFileSystemWriter
{
public:
	virtual cohtml::ISyncStreamWriter* OpenFile(const char* path) override
	{
		FileWriter* writer = new FileWriter(path);
		if (!writer->IsOpen())
		{
			writer->Close();
			return nullptr;
		}
		return writer;
	}
};

static FileSystemWriter fileSystemWriter;
cohtml::SystemSettings sysSettings;
...
// replace the default internal "FileSystemWriter"
sysSettings.FileSystemWriter = fileSystemWriter;

// uncomment to use the default internal "FileSystemWriter"
// sysSettings.FileSystemWriter = nullptr;

cohtml::System cohtmlSystem = cohtmlLibrary->CreateSystem(sysSettings);

...

unsigned profilngLevel = 2;
cohtmlSystem->EnableProfiling(true, "profling_output.json", profilngLevel);

...

cohtmlSystem->EnableProfiling(false, nullptr, 2);

Inspector Profiling vs the new Profiling API

Prysm can also be profiling with its existing integration with the Chrome’s inspector. There are, however, some key differences between the new API and the Recording tab in the inspector.

  • The new API is geared more towards profiling of the C++ code. It introduces less overhead and it’s meant for finer level of performance tracing. The reduced overhead is especially true on the platforms where Prysm can be profiled with native profile markers.
  • The inspector profiling is the only way to see and profile the execution of JavaScript.

Even though these differences do exist, Prysm remains the same system in both cases. For a better understanding of what Prysm does internally and how to profile it effectively, see this profiling and optimization guide.