Those words are probably the most commonly used in every single software update, especially in the Apple App Store and Google Play Store. In the context of a real time 3D simulator like Infinite Flight, performance and stability are absolutely crucial when offering an enjoyable user experience.
With this post, we want to offer more transparency and context for what it actually means when we release "performance improvements" with a new update.
When building a mobile app there are 3 main aspects that need to be optimized: memory, cpu, and power usage. Infinite Flight also makes heavy use of the GPU (Graphics Processing Unit) but we will leave those details out for a potential future post.
Device memory limitations can pose a conundrum for our developers as they work to squeeze new features into an already feature-rich app. Memory, or RAM, (which differs from type of storage that allows you to save photos and apps) refers to an amount of data storage that Infinite Flight can use to complete tasks. If the app tries to use more memory than the device has available, it will likely result in a crash.
"Textures" are usually what use the most memory, both in terms of capacity and bandwidth. Between the terrain imagery and the aircraft liveries, Infinite Flight uses a lot of them, especially with recent aircraft. Most textures are streamed (downloaded from our servers) and loaded as you fly which requires some careful considerations to maintain a good frame rate. This is actually an area that we are looking at improving since currently there can be a noticeable "stutter" in situations where a lot of aircraft are being loaded at the same time in multiplayer.
Device processing power is—to put it simply—the rate at which a processor can perform computations. The clock rate, usually in GHz, indicates how many "cycles" a CPU can perform per second. A 2GHz processor can perform 2 billion cycles per second. Each operation, such as reading from memory, writing to memory, multiplication, addition, and so on, costs a certain number of cycles. This varies depending on the type of processor.
In the context of Infinite Flight, if we add all of the cycles from all of the operations it performs, multiply it by the frame rate we want (30 or 60 fps), that number needs to be under 2 Billion to ensure it runs smoothly on a single 2GHz processor. Easy, right? This might sound like a lot of headroom, but consider that a single main memory read can take hundreds of cycles. It is very important to optimize those, and reading from storage is even slower. In addition to this, we must account for the operating system, and the apps that are running in the background on the device as well.
To add more complexity to the matter, mobile processors often lower their clock rate, known as "throttling", to maintain a certain temperature and power consumption budget. In short, the more cycles an app uses, the slower the processor might get, so it is very important to be very efficient. This is especially true with memory read/write since they usually uses the most cycles.
As mentioned already, power consumption comes down to how many cycles an app uses. It is important to do as much as possible in as few cycles as possible. Memory access is one of the most costly operations in a processor. Optimizing those is key to good performance.
To give you a sense of what a memory access means in terms of performance, let's bring everything to a human scale and consider a very slow processor where 1 cycle takes 1 second. In our hypothetical processor, reading from main memory would take anywhere from 4 to 12 minutes. Reading from storage would take from 15h to 2 days. Requesting a scenery tile from our server would take 6 to 9 months. As you can see, it is crucial to always make sure to optimize for memory access. Thankfully, processors have a few layers of caches that can make those operations much faster if carefully taken into account.
It is all connected
Now that we have briefly explained the various aspects of performance optimizations, let's go through a concrete example.
Our recent aircraft are made of hundreds of thousands of polygons that we need to display at a minimum of 30 frames per second, including animations, shading, etc. In multiplayer, there can be many of those aircraft in view so it is not uncommon to have 1 million+ polygons that are potentially visible, just for the aircraft. The fastest way to draw something is to not draw it at all; when an aircraft is a few hundred meters away, there is no need to draw the interior since it won't be visible (we actually use its size on screen to determine this since we want those details to appear when zooming as well, not only when getting closer).
All of our recent aircraft have multiple levels of detail (simplified versions of the aircraft) that we pick based on its size on screen. This allows us to save some precious CPU/GPU processing power as well as memory bandwidth which results in decreased battery consumption. Those LODs are part of what our artists need to create when making a new aircraft and can be quite time consuming.
There is a lot going on behind the scenes that are often summarized by "performance optimizations" in our release notes. While not being what our audience cares about the most, it is what enables us to push Infinite Flight forward and make all the other features possible.
We see lots of room for improvement for Infinite Flight in spite of the challenges ahead. As devices continue to evolve and as our developers continue to push the boundaries of what's possible, we're confident our user experience will only get better as well.