Skip to content

Runtime Integrations Performance Plan #698

@csciguy8

Description

@csciguy8

(currently work in progress, feedback welcome)

Let this issue propose a methodology for determining performance and to answer...

Is our product performant?
What are the questions we should ask?
How do we answer them?

Applies to Cesium's runtime integrations, but also extends to any project that uses cesium-native in the community.
cesium-unreal
cesium-unity
cesium-omniverse

Background

When we say performance, what are we referring to?

  • Load times - How quickly tiles appear when using a Cesium app
  • Frame rate (FPS) - How smoothly animation is presented
  • Efficient use of device resources - Network, Memory, CPUs, GPUs, etc

How do we measure performance?

  • It must observable - Either through intuitive use, or relevant tools
  • There must be metrics that specify a threshold - Essentially what has been decided as 'good'

The Case for Performance Reporting

We need a baseline. A performance report shows how our products are doing, quickly, without a deep dive of technical data.

The details should be intuitive, whether the reader is in programming, project management, or business development.

Example Report Output

POOR  | Load time when starting an app | 10 sec | [Unreal 5.0][Win][NoCache][Denver]   | CesiumForUnreal
OK    | Load time when starting an app | 2 sec  | [Unreal 5.0][macOS][NoCache][Denver] | CesiumForUnreal
OK    | Load time when starting an app | 1 sec  | [Unreal 5.0][Win][WarmCache][Denver] | CesiumForUnreal 

In the above example, the Cesium for Unreal plugin is being tested for load time, under various conditions. 3 test instances were run with each line corresponding to data about its conditions and passing state.

Reports should help with hard questions

A programmer might ask:

  • Is implementing X optimization worth Y amount of development time?
  • Did X code change help or hurt performance?

A business developer may ask:

  • Are load times ok when running on some-low-spec-device with World Terrain?
  • Will I experience similar framerates if I choose Unreal over Unity?

A product owner could ask:

  • Is performance competitive with similar products on the market?
  • What are the weakest performing use cases that hurt our reputation the most?

Performance Testing

Reports summarize based on data, which comes from performance testing.

Performance tests answer specific questions to predefined use cases. The best tests are simple ones. Ex. "How long did a level take to load?". Add more conditions of the test to create more coverage. Create enough tests with enough coverage, and you are closer to a comprehensive picture of performance.

Test data (even a report) should be generated without user intervention. The ultimate goal would be to run under continuous integration with extensive coverage across device types and use cases.

This is not to be confused with a performance profile, which is invaluable to a programmer fixing a performance problem. Profiles provide information like how long X function took to execute in this frame, the idle time of each CPU, or the number of times memcpy was called. Performance tests on the other hand, focus more on the user situation that was run, and if it fails expectations.

Example Tests

Test 1: Load times when starting an app

      -Common-

      Description: User starts the app at an initial location and waits until the view is fully loaded.
      Measurement: Time from first tile request until final level of detail is presented
      Map Assets:  Cesium Ion World Terrain + Bing Maps Aerial
      Condition Set: [Empty, Warm]             // Cache state
      Condition Set: [Denver, Paris, New York] // Start location

      -Client Specific-

      Condition Set: [Unreal 5.0, Unreal 5.1, Unreal 5.2]
      Condition Set: [Windows, macOS, iOS, Linux, Android]

A pseudo-definition of how we could conceptually define a test.

The common section defines what any runtime integration could implement. It should be described well enough to:

  • Understand the start and end of the test
  • What is being measured
  • Any number of 'Condition Sets' that imply multiple runs of the same test

This shows 2 states the cache can be in (empty or warm) in addition to 3 different locations to start in. This means at minimum 6 (2x3) different instances of the test should be run.

The client specific section would define additional aspects that cesium-native would not know about. This includes the versions of Unreal or platforms that are being built. This would add more conditions sets, multiplying the total runs by 3, then 5, totaling 90 (6x3x5).

Already we see that judicious of use of conditions will be needed to keep report generation time reasonable.

Test 2: Per-tile load times

      Description: Wait until the view is fully loaded, spin around 360 in 10 seconds.
      Measurement: Per-tile loading time (min, max, average)
      Map Assets:  Cesium Ion World Terrain + Bing Maps Aerial
      Condition Set: [Empty, Warm]             // Cache state

Test 3: Frame rate when flying from location to location

      Description: Wait until view is fully loaded. Fly to different locations.
      Measurement: Frames per second during animation (min, max, average)
      Map Assets:  Cesium Ion World Terrain + Bing Maps Aerial
      Condition Set: [Empty, Warm]             // Cache state

The Role of Cesium-Native

Cesium-native does not know the about the project that is using it, but can provide supporting tools and methodology.

It is ultimately the runtime integration's responsibility to integrate performance tests into the project.

Research will be required here:

  • How much code can cesium-native provide for performance testing?
  • How do we get the integration effort to a minimum?
  • How do we share performance tests across multiple different integrations?
  • How do we foster a shared methodology across different integrations?

Unknowns

  • What will be the integration workflow to adopt performance testing?
    For example, if I'm developing for the Cesium for Unreal plugin and want to see performance reporting, I would:

    1. Choose an appropriate automation system. In this case, let's use Unreal Engine's built in solution
    2. Implement performance tests in Unreal (C++), matching cesium-native's recommended cases, or make my own
    3. Register the results of the tests to cesium-native using provided APIs
    4. Generate a report using cesium-native provided scripts (or APIs), or make my own

    This sounds ok, but could it be better?

  • What does this offer implementations on mobile devices (tablets and phones)? Traditionally it is hard to integrate automated performance testing here. Does the shared nature of cesium-native give us an advantage?

  • What does this offer VR / AR / XR headset development?

  • How far into development workflow does this extend? As prevalent as unit tests in CI?

Proposed Task Schedule

(replace with actual issues as they are created)

  • Implement initial performance testing in Cesium for Unreal
  • Move integration-independent code to cesium-native
  • Integrate performance testing in Cesium for Unity
  • Integrate performance testing in Cesium for Omniverse
  • Add reporting features (set acceptable thresholds, generate summary, collate across integrations)
  • (continuous) Add support for critical use cases
  • (continuous) Add support for additional platforms (Linux, macOS, etc)
  • (continuous) Add support for additional devices (phones, tablets, headsets)

Reference

Performance improvements for unreal and native
CesiumGS/cesium-unreal#867

Load tracing in cesium native
#267

Metadata

Metadata

Assignees

No one assigned

    Labels

    performanceImprovements to performance, including reductions in memory usageresearchExplore an idea or prototype a concept and share the results

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions