complete the initial draft of getting-started/sensecom/fakeshm-tuning handbook section

This commit is contained in:
Mamadou Babaei
2026-07-13 20:16:22 +02:00
parent 0f04fea5c2
commit 5ffbaa9a66
7 changed files with 335 additions and 3 deletions
@@ -1,16 +1,330 @@
# SenseGlove FakeShm Module Tuning # SenseGlove FakeShm Module Tuning
Starting with **SenseGlove Libraries `v2.400.0-023e6b23c`**, which is at the heart of **SenseCom v1.10.x** and the **SenseGlove Unreal Engine Plugin v2.9.x**, SenseGlove has introduced a completely new communication backend called **`SGFakeShm`**.
Despite its name, `SGFakeShm` is **not** another shared memory implementation. Instead, it is a modern communication layer that supports multiple transports to imitate the legacy SharedMem behavior using alternative transports and mechanisms on both Microsoft Windows and GNU/Linux, while retaining full compatibility with the existing Shared Memory implementation.
The new module was designed to significantly improve latency, throughput, and frame rate stability while maintaining backward and forward compatibility with previous or future releases of SenseCom or the UE plugin.
## Overview
Prior to this release, communication between SenseCom and applications such as Unreal Engine or Unity relied exclusively on **Boost Shared Memory**.
While the legacy Shared Memory provides good performance, it has several drawbacks:
- Communication is fundamentally blocking.
- Enterprise security software frequently interferes with Shared Memory.
- Multiple applications competing for Shared Memory can negatively impact performance.
- Due to its blocking/synchronous nature of the legacy SharedMem implementation, rendering and communication become more tightly coupled, potentially reducing frame rate where Boost SharedMem becomes the bottleneck.
The new `SGFakeShm` backend addresses these limitations by introducing two additional communication mechanisms/transports:
- **IPC**
- Named Pipes on Microsoft Windows.
- Unix Domain Sockets on GNU/Linux.
- **TCP over loopback (localhost)**
Unlike the legacy Shared Memory implementation, both `IPC` and `TCP` transports support a fully asynchronous, non-blocking architecture, unless explicitly forced to fall back to synchronous/blocking mode via the user-exposed configuration.
This allows communication to happen independently from rendering, reducing stalls and improving frame time consistency.
## Backward and Forward Compatibility
One of the design goals of `SGFakeShm` was **complete backward and forward compatibility**.
Even if your application is still using an **older Unreal Engine plugin**, simply upgrading **SenseCom** allows you to benefit from the improvements made to the Shared Memory transport. The opposite is also correct, you can pair old SenseCom with newer UE plugin that relies on `SGFakeShm` and both still should function as expected.
> [!NOTE]
> If a new version of SenseCom or the UE plugin paired with a version that lacks
> support for `SGFakeShm`, using the default settings, it will always
> automatically fall back to the legacy SharedMem. Thus, we recommend using the
> recent versions of both SenseCom and the UE plugin with support for
> `SGFakeShm` to be able to fully utilize the new capabilities and improvements
> including the new IPC and TCP transports. Otherwise, due to lack of support
> from one party in such setups where one side lacks `SGFakeShm` support, `IPC`
> or `TCP` won't function as expected.
Since the preferred transport is only chosen and configured **centrally via SenseCom** and also the exchanged configurations are versioned, Unreal and Unity plugins automatically detect and follow the selected transport and their enforced settings; as a result the setting only needs to be changed in one place and no configuration from the plugin side is required at all.
This ability allows the plugins or applications to remain forward compatible with SenseCom when future versions are released, thus enables SenseCom to deliver further tweaking and performance improvements in the future.
## Shared Memory Improvements
Although Shared Memory remains a blocking transport by design, it has received numerous internal optimizations. The new implementation provides:
- Reduced latency.
- Higher throughput.
- Various bug fixes.
In our benchmarking, we observed that the legacy SharedMem overhaul has dramatically improved its performance and stability, boosting throughput from only `a few KB/s` to roughly `7.5 GB/s` in certain configurations, compared to the previous implementation.
Applications that still prefer to use `SharedMem` over `IPC` (**Named Pipes** on Microsoft Windows and **Unix Domain Sockets** on GNU/Linux), will therefore still benefit from upgrading SenseCom and the UE plugin, even without adopting the newer `IPC` or `TCP` transports.
These improvements are specifically designed to eliminate bottlenecks and improve reliability in demanding enterprise environments where shared memory can be impacted by security software.
## Transport Configuration
Transport configuration is done in two parts:
- Choosing an IPC mechanism via SenseCom settings.
- Optionally, tweaking and tuning the desired transport for your hardware, operating system, and use case via `sgfakeshm-params.yml`.
### Choosing a Transport via SenseCom Settings
In order to choose an IPC transport/mechanism:
1. Open the click on the hamburger button inside the main SenseCom user interface.
2. From the open menu, choose `Settings`.
3. Navigate to the end of the settings section.
4. Click on the `IPC Method` combo box.
5. Choose your desired IPC method.
![SenseCom Settings - Choosing an IPC Transport/Mechanism](sensecom-sgfakeshm-choosing-ipc-transport.png "SenseCom Settings - Choosing an IPC Transport/Mechanism")
> [!TIP]
> You do not have to close or restart SenseCom, Unreal Editor, or your
> simulation to choose or change an an IPC method and its settings.
>
> Once a new IPC method is selected, both SenseCom and your simulation should
> be able to pick it up almost instantaneously.
### Parameter Tuning
Every `SGFakeShm` supported transport, `IPC`, `TCP`, and `SharedMem` exposes certain configurations and parameters that can further be tweaked to acheive optimal performance. While we provide sane defaults that should work well for most people out of the box, there is no single configuration that is optimal for every system, hardware, or use case. Every operating system schedules threads differently. Likewise, different communication mechanisms have different performance characteristics. For example:
- Microsoft Windows generally benefits from slightly larger timeout values.
- GNU/Linux often performs best with much lower timeout values.
- `IPC` and `TCP` transports behave differently under high load. For example, while both work best when the `SocketReceiveNonBlocking` parameter set to `true`, their behavior differ from each other depending on the value set for `SocketSendNonBlocking`. Our benchmarking with a `10K` payload size reveals, on our test hardware, IPC performs better when the value for this parameter is set to `false`, while TCP performs better when it's been set to `true`.
- Desktop applications and VR applications often have different latency requirements.
- Low-power embedded devices may prefer lower CPU usage over absolute minimum latency.
As a result, the default configuration shipped with SenseCom has been carefully selected to provide excellent performance for the vast majority of users. So, most users **do not really need to modify these values**.
However, advanced users who wish to squeeze every last bit of performance out of their particular hardware can optionally do so.
### Some Notes Regarding Latency and Throughput
In our benchmarks and on our test hardware, using the payload size of `1 MB`, `SharedMem` consistently acheived the follwoing stats:
- Read Throughput: roughly `7.5 GB/s`.
- Write Throughput: roughly `4.0 GB/s`.
- Smoothed Latency on Microsoft Windows: roughly `15 ms`.
- Smoothed Latency on GNU/Linux: roughly `5 ms`.
The same benchmark via the `TCP` transport and using fine-tuned settings consistently yielded:
- Read Throughput: roughly `2.1 GB/s`.
- Write Throughput: roughly `2.1 GB/s`.
- Smoothed Latency on Microsoft Windows: roughly `70 μs`.
- Smoothed Latency on GNU/Linux: roughly `40 μs`.
The same benchmark via the `IPC` transport and using fine-tuned settings consistently yielded:
- Read Throughput: roughly `2.2 GB/s`.
- Write Throughput: roughly `2.2 GB/s`.
- Smoothed Latency on Microsoft Windows: roughly `100 μs`.
- Smoothed Latency on GNU/Linux: roughly `50 μs`.
> [!IMPORTANT]
> While various payload sizes are supported, e.g., `1 KB`, `10 KB`, `100 KB`,
> `1 MB`, and `10 MB`, we recommend tuning your SenseCom installation by
> choosing the `10 KB` payload size.
>
> The reason for this recommendation is, typically the SenseCom payload size
> falls somewhere in between `1 KB` to `10 KB`. Thus, tuning using `10 KB`
> payload size will be as close as possible to real-world SenseCom usage in
> production.
> [!NOTE]
> Regardless of the payload size on Microsoft Windows, in our tests, Boost
> `SharedMem` latency mostly stayed above `15 ms`. Due to its blocking nature,
> this makes it less suitable for simulations that need to exceed `60 FPS`,
> especially when `SharedMem` is restricted or throttled by security software.
> Since the rendering thread will be blocked while waiting on `SharedMem`, if
> the latency rises above `1000 / 60 = 16.6666666667 ms`, the framerate will
> suffer and you may experience jitter or lag, regardless of how powerful your
> hardware is.
>
> Also, there have been some reports that when `SharedMem` is throttled, even if
> your simulation is not running, this could still cause jitter inside the Unreal
> Editor itself.
>
> In this case, we recommend switching to `IPC` or `TCP` due to their low
> latency. Despite their lower throughput compared to Boost `SharedMem`, the
> latency of these alternative transports is in the realm of microseconds,
> making them significantly faster than Boost SharedMem, whose latency is
> measured in milliseconds.
### Benchmarking and Tuning Utilities
To assist advanced users, SenseGlove provides two simple yet powerful benchmarking applications with versatile benchmarking capabilities:
- **sgfakeshm-connect-client**
- **sgfakeshm-core-client**
These utilities are distributed through the [**SenseGlove Unreal Engine Plugin Azure DevOps repository**](https://dev.azure.com/SenseGlove/_git/SenseGlove-Unreal) and are **not included in the [official Fab Store release](ttps://www.fab.com/listings/62bcdd2a-0bb1-4f34-b7b8-c5e7c9313099)**.
The utilities allow developers to:
- Benchmark latency.
- Benchmark throughput.
- Compare IPC, TCP and Shared Memory performance side by side.
- Experiment with different parameter values
- Optimize configurations for a specific operating system or hardware.
- Tune parameters for particular workloads.
Because communication performance depends on the operating system, CPU scheduler, hardware and transport type, these tools provide the easiest way to determine the optimal settings for your own environment.
#### sgfakeshm-connect-client
`sgfakeshm-connect-client` is the main benchmarking application, which acts like SenseCom. Between the two applications, the transport configuration happens on this app.
![SGFakeShm Benchmarking and Tuning Utilities - sgfakeshm-connect-client running on GNU/Linux](sgfakeshm-connect-client-gnu-linux.png "SGFakeShm Benchmarking and Tuning Utilities - sgfakeshm-connect-client running on GNU/Linux")
![SGFakeShm Benchmarking and Tuning Utilities - sgfakeshm-connect-client running on Microsoft Windows](sgfakeshm-connect-client-microsoft-windows.png "SGFakeShm Benchmarking and Tuning Utilities - sgfakeshm-connect-client running on Microsoft Windows")
`sgfakeshm-connect-client` supports the following keyboard shortcuts:
- `ESC`, `Q`, or `Ctrl+C` to exit the application.
- `1` to toggle and enable or disable the `TCP` transport.
- `2` to toggle and enable or disable the `IPC` transport.
- `3` to toggle and enable or disable the `SharedMem` transport.
- `S` to switch between various predefined payload sizes, e.g., `1 KB`, `10 KB`, `100 KB`, `1 MB`, and `10 MB`.
It also supports the following command-line parameters in order to change the tuning parameters via command-line:
```sh
$ ./sgfakeshm-connect-client --help
Usage:
sgfakeshm-connect-client [options]
Options:
--help or -h
--tcp <yes|no>
--ipc <yes|no>
--sharedmem <yes|no>
--socket-receive-nonblocking <yes|no>
--socket-receive-timeout-ms <int32>
--socket-send-nonblocking <yes|no>
--socket-send-timeout-ms <int32>
--socket-reconnect-time-min-ms <int32>
--socket-reconnect-time-max-ms <int32>
--worker-retry-interval-ms <uint64>
--heartbeat-interval-ms <uint64>
--liveness-timeout-ms <uint64>
--latency-smoothing-window-ms <uint64>
--throughput-smoothing-window-ms <uint64>
--shared-mem-heartbeat-block-size <uint32>
--shared-mem-liveness-timeout-ms <uint64>
```
It is however, much faster and easier to modify the configuration file instead of passing arguments to `sgfakeshm-connect-client` as [it supports hot reloading](#hot-reloading).
The following symbols indicate:
- ✅: the specific transport is enabled.
- ❌: the specific transport is disabled.
- 🟢: the specific transport is connected and `./sgfakeshm-core-client` is prensent on the other side.
- 🔴: the specific transport is disconnected and `./sgfakeshm-core-client` might not be prensent on the other side.
#### sgfakeshm-core-client
`sgfakeshm-core-client` is the companion benchmarking application, which acts like your Unreal Engine or Unity plugin, and consists of two tabs. The first one is the `Benchmark` tab to verify the benchmarking latency and throughput from the second peer app, and the second one is the `Tuning Info` tab to verify if the `sgfakeshm-connect-client`-enforced optimizations have indeed been applied.
![SGFakeShm Benchmarking and Tuning Utilities - sgfakeshm-core-client running on GNU/Linux - Benchmark Tab](sgfakeshm-core-client-benchmark-tab-gnu-linux.png "SGFakeShm Benchmarking and Tuning Utilities - sgfakeshm-core-client running on GNU/Linux - Benchmark Tab")
![SGFakeShm Benchmarking and Tuning Utilities - sgfakeshm-core-client running on GNU/Linux - Tuning Info Tab](sgfakeshm-core-client-tuning-info-tab-gnu-linux.png "SGFakeShm Benchmarking and Tuning Utilities - sgfakeshm-core-client running on GNU/Linux - Tuning Info Tab")
![SGFakeShm Benchmarking and Tuning Utilities - sgfakeshm-core-client running on Microsoft Windows](sgfakeshm-core-client-microsoft-windows.png "SGFakeShm Benchmarking and Tuning Utilities - sgfakeshm-core-client running on Microsoft Windows")
`sgfakeshm-core-client` supports the following keyboard shortcuts:
- `ESC`, `Q`, or `Ctrl+C` to exit the application.
- `S` to toggle between various predefined payload sizes, e.g., `1 KB`, `10 KB`, `100 KB`, `1 MB`, and `10 MB`.
- `B` to switch to the `Benchmark` tab.
- `T` to switch to the `Tuning Info` tab.
The following symbols indicate:
- ✅: the specific transport is enabled.
- ❌: the specific transport is disabled.
- 🟢: the specific transport is connected and `./sgfakeshm-connect-client` is prensent on the other side.
- 🔴: the specific transport is disconnected and `./sgfakeshm-connect-client` might not be prensent on the other side.
### Important Benchmarking Limitation
The benchmarking utilities use the **NNG `Pair0` protocol** for `IPC` and `TCP` transports.
`Pair0` is intentionally designed as a **one-to-one communication protocol**, meaning that only one peer (one listener and one dialer) may exist and run at any given time.
Because of this limitation:
- **Never run multiple instances of `sgfakeshm-connect-client` simultaneously.**
Likewise:
- **Never run multiple instances of `sgfakeshm-core-client` simultaneously.**
Running multiple instances of either application at the same time will cause the benchmark applications to fail or crash because they attempt to establish multiple `Pair0` connections.
So, this means at the time of benchmarking no instances of SenseCom or UE or Unity plugins should be running either.
### The Configuration File
Depending on the platform **`SGFakeShm`-dependant applications** (such as SenseCom, UE plugin, or the benchmarking/tuning apps) are running on, all tuning parameters are generated or loaded from:
- `${XDG_CONFIG_HOME:-$HOME/.config}/SenseGlove/sgfakeshm-params.yml` on GNU/Linux, which typically equates to `~/.config/SenseGlove/sgfakeshm-params.yml`.
- `%USERPROFILE%\Documents\SenseGlove\sgfakeshm-params.yml` on Microsoft Windows.
When SenseCom or `sgfakeshm-connect-client` start:
- If the file does **not** exist, it will automatically be generated.
- If the file exists and its version matches the currently supported version, its values override the built-in and hardcoded defaults.
- If the file format is not a valid YAML, or it contains invalid values, or the file version does not match a version that is shipped with the current `SGFakeShm` version, the existing file is preserved by renaming it to `sgfakeshm-params.yml.YYYY-MM-DD-hh-mm-ss`, and then a new configuration file containing the latest defaults is then generated automatically.
This approach allows users to preserve previous configurations while safely switching between various versions, whether old or new.
### Hot Reloading
One particularly useful feature is that the configuration file supports **hot reloading**.
Whenever the file is saved:
- SenseCom automatically detects the changes.
- The configuration is reloaded.
- The new parameters take effect immediately.
Restarting SenseCom or applications using the SenseGlove libraries is therefore unnecessary.
This makes iterative tuning significantly easier.
### Exposed Tuning Parameters
The generated `sgfakeshm-params.yml` file always contains generic documentation, along with a detailed explanation of every exposed tuning parameter and its default value. The following is the latest version of `sgfakeshm-params.yml` generated by the latest release of `SGFakeShm` at the time of writing:
```yaml ```yaml
# File name used for tweaking and tuning the FakeShm parameters. # File name used for tweaking and tuning the FakeShm parameters.
# When this file does not exist it will be generated by the SGConnectShm upon # When this file does not exist it will be generated by the SGConnectShm upon
# initialization or reconfiguration and gets populated from the hardcoded values # initialization or reconfiguration and gets populated from the hardcoded values
# below. # below.
# If it does indeed exist and file version matches the version supported by the # If it does indeed exist and file version matches the version supported by the
# current release of the SenseGlove libraries, the parameters values in this # current release of the SenseGlove libraries, the parameter values in this file
# file will override the hardcoded values from the libraries. # will override the hardcoded values from the libraries.
# If the file has invalid values, or the version number does not match, it will # If the file has invalid values, or the version number does not match, it will
# be renamed to sgfakeshm-params.yml.YYYY-MM-DD-hh-mm-ss to # be renamed to sgfakeshm-params.yml.YYYY-MM-DD-hh-mm-ss to
# preserve the user's choosen values and a new file will be generated containing # preserve the user's chosen values and a new file will be generated containing
# the updated values or newly introduced parameters. # the updated values or newly introduced parameters.
# #
# NOTE: This file supports hot-reloading upon saving the file. Thus, you do # NOTE: This file supports hot-reloading upon saving the file. Thus, you do