What is Data-Oriented ECS
This article will discuss a rather interesting implementation Entity Component System (ECS)namely about Data-Oriented ECS (DOD ECS). This article is suitable for those who want to get acquainted with ECSand in particular with his DOD ECS implementation. This article will not go into the details of specific implementations or optimizations, but will instead describe the fundamental difference between the classical ECS And DOD ECSfeatures, advantages and disadvantages are given DOD ECS.
![Entity Component Systems Entity Component Systems in Elixir - DZone](https://habrastorage.org/getpro/habr/upload_files/edc/d46/9b3/edcd469b3e8e5275b07a78731bdd18b7.png)
What is ECS
Before moving on to DOD versions, let's look at the classical approach. Entity Component System (ECS) – an architectural pattern used in programming to manage and organize data and logic using the principle of object composition. It was developed as an alternative to traditional object-oriented programming.
Advantages over OOP:
Flexibility. Composition of objects ECS allows you to easily add new components to entities without increasing the number of inheritances of the object.
Scalability. ECS allows you to create complex relationships between entities through systems.
Performance. Separation of data and logic ECS allows better use of cache memory and speeds up operations.
Basic principles ECS:
Entity. An entity is a unique container for components. It does not contain data or logic itself, but rather links components and systems. Entities allow you to identify objects in a system, such as game characters, interface elements, or other objects.
Component. A component is a set of data that describes a specific characteristic of an entity. It contains only data and does not include the logic for processing it. For example, a component may include information about the position, speed, color, or health of an entity.
System. The system implements the logic of processing and interaction between components. It receives data from components and processes it. Systems work with entities that contain certain components and perform actions based on this data. For example, the system can update the position of entities depending on their speed or process interactions between entities.
![](https://habrastorage.org/getpro/habr/upload_files/a32/6e3/b99/a326e3b9908a855ba693a8504712c2ca.png)
Let's look at an example of a simple game engine. ECS There may be entities such as players, enemies, and items. Components for these entities may include position, speed, health, etc. Systems may handle movement logic (using position and speed components), collision logic (using position and collision components), and rendering (using render components).
Code example:
struct Component {};
// Пример компонента
struct Position : public Component {
std::array<float, 2> Pos;
};
// Пример сущности
struct Entity {
int id;
std::vector<Component*> components;
};
// Пример системы
class MovementSystem {
public:
void update(std::vector<Entity>& entities) {
for (auto& entity : entities) {
if (entity.hasComponent<Position>()) {
Position* pos = entity.getComponent<Position>();
pos->pos.first += 0.5f;
pos->pos.second += 0.5f;
}
}
}
};
What's happened Data-Oriented ECS
Data-Oriented ECS (DOD ECS) — is a specialized version of an architectural pattern ECSfocused on optimizing data storage and increasing performance. Unlike traditional ECSwhich focuses on separating data and logic, DOD ECS focuses on how data is organized and processed to make the most efficient use of hardware resources such as cache memory and processor cores.
Basic principles DOD ECS:
Data organization. Component data is stored in arrays (this involves using data structures such as “Array of Structures”), which allows for a more compact and consistent arrangement of data in memory. This differs from the traditional ECSwhere components can be scattered throughout memory and connected to entities via references.
Optimizing data access. Organizing data into arrays helps minimize cache misses and improves performance by allowing more consistent access to memory. Organizing data in this way also allows for efficient use of processor pipelining and improves multithreading because data for processing can be organized to minimize blocking and thread contention.
![](https://habrastorage.org/getpro/habr/upload_files/b73/6c3/af7/b736c3af7dc740a945c9c3793401b9ee.png)
Let's look at an example of use DOD ECS in the game engine. In the classic ECS The player can be represented by an entity that contains Position, Velocity, and Health components. DOD ECS The data of these components will be stored in separate arrays: the Positions array, the Velocities array, and the Healths array.
For example, MovementSystem is responsible for the character's movement – the system will only work with the data in the Velocities and Positions arrays. Since the data is stored in arrays, the system can efficiently process the data, updating positions, minimizing cache misses, and providing faster processing.
Code example
// Пример хранения данных в DOD ECS
struct PositionComponent {
std::vector<std::array<float, 2> pos;
};
// Пример системы в DOD ECS
class MovementSystemDOD {
public:
void update(PositionComponent& positions) {
for (size_t i = 0; i < positions.pos.size(); ++i) {
positions.pos[i].first += 0.5f;
positions.pos[i].second += 0.5f;
}
}
};
Why do we need Data-Oriented ECS
DOD ECS provides a number of significant advantages over traditional ECShowever, it also has its drawbacks. This chapter is dedicated to describing the pros and cons DOD ECS, some of them also touch upon the classical ECS.
Advantages
Optimizing Caching. Component data is stored in arrays (e.g. Array of Structures), which improves data locality and reduces the number of cache misses.
Simplifying processingSince data is stored sequentially, it can be accessed faster, improving overall system performance.
Parallelism: Organizing data into arrays simplifies the distribution of tasks between threads. This allows for the efficient use of multiprocessor systems and improves scalability.
Reducing blockages. Multithreaded systems can process data in parallel, minimizing blocking and thread contention for resources.
Ease of adding new systems. IN DOD ECS Adding new systems or components often does not require changes to existing parts of the code.
Isolation of changesBecause data and logic are separated, a change to one system or component does not affect other parts of the system.
Minimizing fragmentationStoring data in arrays helps minimize memory fragmentation.
Flaws
Complexity of data structuring. Designing a system using DOD ECS can be more complex because of the need to carefully consider how the data will be organized and how systems will interact with it.
Data managementSeparation of data and logic can make code more complex and difficult to understand, since the logic for processing data is in systems and the data is in components. This can make the code difficult to debug and understand.
Limited adaptabilityIn some cases, the data structure may be less flexible than the object-oriented approach.
Integration with other systems. Integration DOD ECS with other architectural patterns or existing systems can be challenging, especially if the other systems are oriented toward object-oriented design.
Conclusion
Data-Oriented ECS provides many benefits, including improved performance, efficient use of multithreading, and flexibility in adding new systems and components. However, it also requires careful design, can increase code complexity, and has limited flexibility in some cases. Deciding whether to use DOD ECS should be based on performance requirements, project complexity, and development team experience.
Links from where I stole the pictures