A coroutine-based parallel discrete event simulation engine scheduling method and device
Patent Information
- Application Number
- CN202610935971.8
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2026-06-26
- Publication Date
- 2026-10-13
AI Technical Summary
这些技术问题直接关系到复杂体系仿真的可行性与实用性,是构建高逼真度虚拟环境的关键技术瓶颈
本发明所公开的一种基于协程的并行离散事件仿真引擎调度方法,基于协程的协作式调度机制、轻量级上下文切换技术及确定性事件推进方法,通过优化调度架构确保大规模仿真系统的高并发性、低延迟特性和因果逻辑正确性,实现性能大幅提升,采用用户态协程替代传统线程,上下文切换开销降至纳秒级,内存占用从MB级降至KB级,可支持数十万级仿真实体并发,解决传统多线程调度上下文切换开销大、内存占用高的问题;通过混合调度,逻辑密集型任务用协程、计算密集型任务用线程池,兼顾并发效率与计算性能,适配复杂体系仿真全场景,从而为体系对抗仿真与效能评估构建高性能计算基础。
Smart Images

Figure CN122903123A_ABST
Abstract
Description
Technical Field
[0001] This invention relates to the field of simulation technology, specifically to a scheduling method and apparatus for a parallel discrete event simulation engine based on coroutines. Background Technology
[0002] System simulation constructs a virtual environment to simulate the interactions of various elements in the concurrent scheduling of complex, large-scale entities, providing a scientific means for decision-making, the development of new hardware platforms, and the verification of platform application effects. Traditional single-platform, single-element simulation modes can no longer meet the needs of complex system simulation; therefore, it is necessary to construct a large-scale complex system simulation environment composed of multi-domain, multi-type simulation models.
[0003] Simulation engine scheduling technology is one of the core technologies supporting large-scale system-on-system simulation. In complex system simulation applications, it is necessary to coordinate the operation of hundreds or even tens of thousands of simulation entities. These entities are distributed across different logical nodes, covering multiple application domains and involving multiple functions such as perception, decision-making, execution, and assurance. The simulation engine scheduling system is mainly responsible for the unified management of the operation process of these entities, ensuring that each entity executes according to the correct temporal logic, maintaining the temporal consistency, causal logic correctness, and real-time performance of the simulation system. Especially in new application styles such as manned / unmanned collaboration and cross-domain collaboration, the interaction between simulation entities is more complex, posing higher technical requirements to the scheduling system.
[0004] In traditional simulation engine architectures, multithreading is widely used to implement concurrent scheduling. However, as the scale of simulations continues to expand, multithreaded scheduling faces several technical bottlenecks. The primary problem is the significant overhead of context switching. Thread switching involves transitions between kernel and user modes, each requiring microseconds. When the number of entities reaches thousands, this switching overhead becomes a significant performance bottleneck. Secondly, memory consumption is high. Each thread requires a stack space of at least a megabyte, leading to enormous memory consumption in large-scale concurrent scenarios. Thirdly, determinism is difficult to guarantee. The preemptive scheduling mechanism of threads is affected by the operating system's scheduling policy, potentially resulting in unreproducible simulation results. Finally, the number of concurrent threads is limited. Operating systems inherently restrict the total number of threads, typically making it difficult to support concurrent scheduling of tens of thousands of entities.
[0005] The existing simulation engine scheduling suffers from performance bottlenecks and deterministic assurance issues. First, it's necessary to overcome the performance bottleneck of large-scale entity concurrent scheduling. When the number of simulated entities reaches tens of thousands, traditional multi-threaded scheduling faces problems such as high context switching overhead, high memory consumption, and limited concurrency, leading to low simulation efficiency or even failure to run normally. Second, the deterministic nature of simulation timing needs to be addressed. A cooperative scheduling mechanism is needed to ensure the controllability of event processing order and the reproducibility of simulation results, avoiding battlefield situation distortion caused by scheduling uncertainty. These technical issues directly relate to the feasibility and practicality of complex system simulation and are key technical bottlenecks in building highly realistic virtual environments.
[0006] To address the aforementioned technical bottlenecks, coroutine technology provides an innovative solution for simulation engine scheduling. A coroutine is a lightweight user-space thread whose scheduling process is controlled by the program itself, offering advantages such as low switching overhead, small memory footprint, and high concurrency. Employing a coroutine scheduling mechanism in a simulation engine can effectively solve the performance problems of large-scale entity concurrency while ensuring the determinism and reproducibility of the simulation.
[0007] This application aims to solve key technical challenges such as entity concurrent scheduling, event processing efficiency, and time synchronization accuracy in large-scale simulation applications, and to provide technical support for efficient collaborative simulation of elements from different fields. Summary of the Invention
[0008] This invention aims to overcome the aforementioned deficiencies of the prior art and provide a scheduling method and apparatus for a parallel discrete event simulation engine based on coroutines. To achieve the above objective, a first aspect of this invention discloses a scheduling method for a parallel discrete event simulation engine based on coroutines, the method comprising: S1. Obtain simulation configuration information; the simulation configuration information includes simulation configuration file, hardware resource parameters, simulation scenario and several entity data, etc.; the entity data includes entity behavior dimensions, complexity score, priority and other information; S2. Initialize the simulation scheduling framework according to the simulation configuration information to obtain a ready-state simulation scheduling framework; the simulation scheduling framework includes an entity coroutine pool, a coroutine scheduler, an event queue, a time manager, a thread pool, and a hierarchical time slot scheduler; S3. Process the pending event information input by the user to obtain the pending event queue; S4. The queue of events to be processed is processed using the ready-state simulation scheduling framework to obtain simulation results.
[0009] As an optional implementation, in a first aspect of the present invention, the initialization of the simulation scheduling framework based on the simulation configuration information to obtain a ready-to-go simulation scheduling framework includes: S21. Obtain entity data information from the simulation configuration information; S22. The entity data information is processed using a preset entity complexity classification calculation model to obtain entity behavior complexity classification information. The expression for the hierarchical calculation model of entity complexity is: in, For entities The complexity of entity behavior; This refers to the number of dimensions of entity behavior, such as perception, decision-making, maneuvering, and attack. ≥3; For the first The weights of each behavioral dimension ,and ; For entities In the The algorithm scores the complexity of each behavioral dimension, with a value ranging from 0 to 100. This algorithm can accurately quantify the behavioral complexity of different entities and avoid redundancy or insufficiency in stack memory allocation. S23. Process the entity behavior complexity classification information to obtain the coroutine stack size information corresponding to the entity. S24. Create an entity coroutine pool based on the coroutine stack size information corresponding to the entity; S25. Initialize the coroutine scheduler, event queue, time manager, thread pool, and hierarchical time slot scheduler; S26. Integrate the entity coroutine pool, coroutine scheduler, event queue, time manager, thread pool, and hierarchical time slot scheduler to obtain the ready-state simulation scheduling framework.
[0010] As an optional implementation, in a first aspect of the present invention, the timing of creating the entity coroutine pool includes: S241. Before engine startup: Entities are directly added to the entity mapping via addEntity(), and start() is called in batches to create coroutines when the engine starts. S242. Engine running: Entities are added through the pending_entities_ queue, and start() is called in runStep() to create a coroutine; S243, Snapshot Recovery: When restoring an entity from a snapshot, call start(ctx, true) to create a coroutine and maintain the original wake-up time; S244. Establish a 1:1 mapping relationship between coroutines and entities, with each entity corresponding to one coroutine.
[0011] As an optional implementation, in the first aspect of the present invention, the entity coroutine pool uses a coroutine pool hash index reuse algorithm to create an index of coroutines within the coroutine pool; The formula for the coroutine pool hash index reuse algorithm is as follows: in, For the index of coroutines within the pool, As a unique identifier for an entity, () represents the hash function, using the SHA-256 hash algorithm. This represents the current total capacity of the coroutine pool. This algorithm enables rapid coroutine location and reuse, reducing the overhead of creation and destruction.
[0012] In another optional embodiment, the entity coroutine pool adopts a dynamic expansion algorithm to dynamically expand its capacity, ensuring that the capacity of the coroutine pool meets the needs of large-scale entity concurrency. The expression for the dynamic expansion algorithm of the coroutine pool is: in, To expand the capacity of the coroutine pool, The current total capacity of the coroutine pool is δ, which is the expansion factor, ranging from 0.2 to 0.5. The number of coroutines currently in use, when Expansion is triggered at certain times.
[0013] As an optional implementation, in the first aspect of the present invention, processing the user-inputted event information to obtain a queue of events to be processed includes: S31. Collect pending events input by the user; the pending events include entity interaction events, time progression events, external instructions, and internal state update data; S32. Encapsulate the events to be processed to obtain a set of events to be processed; S33. The set of events to be processed is sorted using the timestamp min-heap sort algorithm to obtain the first event queue; S34. Merge and deduplicate similar events in the first event queue whose timestamp difference is less than a preset time difference threshold to obtain a queue of events to be processed.
[0014] As an optional implementation, in the first aspect of the present invention, the timestamp min-heap sorting algorithm uses an event priority dynamic adjustment model to calculate event priority values, and sorts the set of events to be processed in order according to the calculated priority values; The expression for the event priority dynamic adjustment model is: in, This represents the dynamic priority of the event, with a value ranging from 0 to 10. This is the time weight, with a value ranging from 0.4 to 0.6; is the entity importance weight, ranging from 0.4 to 0.6; T is the event timestamp. This is the current global simulation time; To find the minimum value, avoid a denominator of 0. ; The importance score of the target entity is given, with a value ranging from 1 to 5.
[0015] As an optional implementation, in the first aspect of the present invention, the step of processing the queue of events to be processed using the ready-state simulation scheduling framework to obtain simulation results includes: S41. The coroutine scheduler retrieves the top event from the queue of events to be processed, and obtains the current event and the target entity ID; S42. Update the global simulation time to the timestamp of the current event; S43. Locate and wake up the corresponding coroutine for the current event based on the target entity ID; S44. Determine the task type of the current event to obtain the task type; the task type is either a logic-intensive task or a computation-intensive task. If the task type is a logic-intensive task, then proceed to step S45; If the task type is a computationally intensive task, then proceed to step S46; It should be noted that this solution does not use completely consistent processing logic for logic-intensive tasks and computation-intensive tasks. Instead, it performs more granular classification processing based on task type and computational intensity. By introducing a hybrid scheduling of coroutines and thread pools, logic-intensive tasks use coroutines and computation-intensive tasks use thread pools, instead of using only a single scheduling mode, which improves processing efficiency. S45. The ready-state simulation scheduling framework processes the current event as a logic-intensive task, and executes step S47 after the processing is completed. S46. The ready-state simulation scheduling framework processes the current event as a computationally intensive task, and executes step S47 after the processing is completed. S47. Determine whether the simulation time has reached the end condition or a stop command has been received, and obtain the second judgment result; If the second judgment result is yes, exit the main loop and execute step S48; If the second judgment result is negative, proceed to step S41; S48. The system outputs the simulation results to the subsequent analysis or visualization process and performs resource release.
[0016] As an optional implementation, in the first aspect of the present invention, determining the task type of the current event to obtain the task type includes: S441. Calculate the overall task complexity of the current event using the task complexity calculation model; The calculation method for the task complexity calculation model is as follows: in, For the current event The overall task complexity is given by λ, where λ is the computational weight. Calculate the number of cycles required for the task. The amount of data processed by the task; S442. Based on the overall task complexity of the current event, the computational density determination model is used to calculate and obtain the computational density value of the current event. The expression for the computational density determination model is: in, For the current event The computational density value, For the overall complexity of the task, For coroutine execution time slices, This refers to the hardware performance coefficient. S443. If the computational density value of the current event is greater than the preset density threshold, the task type of the current event is set to a logic-intensive task; otherwise, it is set to a computation-intensive task.
[0017] As an optional implementation, in the first aspect of the present invention, the ready-state simulation scheduling framework processes the current event as a logic-intensive task, and after processing, executes step S47, including: S451. The legality of the coroutine corresponding to the current event is judged to obtain a first judgment result; If the first judgment result is negative, proceed to step S41; When the first judgment result is yes, step S452 is executed; S452. The coroutine corresponding to the current event is executed in user mode to process logic without kernel mode switching, updating the entity state and generating subsequent events. S453, The coroutine corresponding to the current event calls yield to relinquish CPU execution rights, saves the context, and switches to a suspended state; S454. The ready-to-go simulation scheduling framework writes the latest entity state into shared memory, submits subsequent events to the event queue to be processed, and transfers control to the coroutine scheduler, executing step S47.
[0018] As an optional implementation, in a first aspect of the present invention, the hierarchical time slot scheduler employs a hierarchical time slot scheduling process to manage the suspension and resumption of coroutines; the hierarchical time slot scheduling process includes: When a coroutine is suspended, the wake-up time is calculated and added to the corresponding level of the hierarchical time slot; As time progresses, expired coroutine handles are collected into the ready_events vector through a cascading check mechanism; Batch resume execution of expired coroutines to reduce function call overhead.
[0019] As an optional implementation, in the first aspect of the present invention, the timing of suspending the system management coroutine includes: • Active suspension (time-driven): The entity calls co_await wait() to wait for a specified time; • Passive suspension (event-driven): The coroutine ends when the entity is destroyed by calling co_return.
[0020] As an optional implementation, in the first aspect of the present invention, the recovery timing of the system management coroutine includes: • Time Expiration Recovery: Recover expired coroutines when the layered time slots advance; • Message-triggered recovery: System messages or entity messages trigger immediate recovery.
[0021] As an optional implementation, in the first aspect of the present invention, the system adopts a cooperative event-driven scheduling mechanism to ensure that events are executed in chronological order, thereby guaranteeing the determinism and reproducibility of the simulation timing. Specifically: The coroutine scheduler retrieves the top event (with the smallest timestamp) from the queue of pending events. Update the global simulation time to the timestamp of the current event; Locate and activate the corresponding coroutine based on the target entity ID; After a goroutine finishes processing the current event, it voluntarily relinquishes execution control. The coroutine scheduler continues processing the next event.
[0022] As an optional implementation, in the first aspect of the present invention, the system destroys the coroutine in the following scenarios: • Entity destruction is triggered by: combat damage, fuel depletion, or mission completion; • Coroutine terminates naturally: entity is in a dead state or near-death state; • Exception handling: EntityDestroyedException causes the coroutine to exit gracefully; • Destruction and destruction: The SimTask destructor automatically destroys the coroutine handle.
[0023] As an optional implementation, in the first aspect of the present invention, the ready-state simulation scheduling framework processes the current event as a computationally intensive task, and after processing, executes step S47, including: S461. The coroutine corresponding to the current event encapsulates the computation task into an asynchronous task, binds the coroutine ID, actively suspends the task, and saves the coroutine context. S462. The coroutine scheduler submits the asynchronous task to the thread pool; S463. The thread pool executes computation tasks in parallel to obtain computation results; S464. The coroutine scheduler wakes up the coroutine and restores the coroutine context, merges the calculation results into the entity state, and the coroutine continues to execute subsequent logic. S465, Update thread pool utilization, clean up temporary resources, complete hybrid scheduling and return control; S466. After the event is processed, the coroutine voluntarily relinquishes its execution right, the coroutine scheduler updates the global simulation time, and executes step S47.
[0024] A second aspect of this invention discloses a scheduling device for a parallel discrete event simulation engine based on coroutines, used to implement a scheduling method for a parallel discrete event simulation engine based on coroutines disclosed in the first aspect of this invention. The device includes: The simulation configuration information acquisition module is used to acquire the simulation configuration information input by the user; the simulation configuration information includes simulation configuration files, hardware resource parameters, simulation scenarios, and several entity data, etc. The simulation scheduling framework initialization module is used to initialize the simulation scheduling framework according to the simulation configuration information to obtain a ready-state simulation scheduling framework; the simulation scheduling framework includes an entity coroutine pool, a coroutine scheduler, an event queue, a time manager, a thread pool, and a hierarchical time slot scheduler; The event queue generation module is used to process the user-input event information to obtain the event queue. The event processing module uses the ready-state simulation scheduling framework to process the queue of events to be processed and obtain simulation results.
[0025] Compared with the prior art, the embodiments of the present invention have the following beneficial effects: This invention discloses a scheduling method for a parallel discrete event simulation engine based on coroutines. Based on a cooperative scheduling mechanism using coroutines, lightweight context switching technology, and a deterministic event advancement method, it optimizes the scheduling architecture to ensure high concurrency, low latency, and causal logic correctness of large-scale simulation systems, achieving a significant performance improvement. By replacing traditional threads with user-mode coroutines, context switching overhead is reduced to the nanosecond level, and memory usage is reduced from the MB level to the KB level, supporting hundreds of thousands of concurrent simulation entities. This solves the problems of high context switching overhead and high memory usage in traditional multi-threaded scheduling. Through hybrid scheduling, coroutines are used for logic-intensive tasks, while thread pools are used for computationally intensive tasks, balancing concurrency efficiency and computational performance. This adapts to all scenarios of complex system simulation, thus building a high-performance computing foundation for system adversarial simulation and performance evaluation. Attached Figure Description
[0026] Figure 1 This is a schematic diagram of a scheduling method for a parallel discrete event simulation engine based on coroutines, as disclosed in an embodiment of the present invention. Figure 2 This invention discloses a coroutine scheduling architecture according to an embodiment of the present invention; Figure 3 This is a flowchart of a cooperative scheduling process disclosed in an embodiment of the present invention; Figure 4 This invention discloses a resource allocation strategy process according to an embodiment of the present invention; Figure 5 This is a performance comparison chart of coroutines and threads disclosed in an embodiment of the present invention; Figure 6 This is a schematic diagram of a scheduling device for a parallel discrete event simulation engine based on coroutines, as disclosed in an embodiment of the present invention. Detailed Implementation
[0027] The technical solutions of the embodiments of the present invention will be clearly and completely described below with reference to the accompanying drawings. Obviously, the described embodiments are only some embodiments of the present invention, and not all embodiments. Based on the embodiments of the present invention, all other embodiments obtained by those skilled in the art without creative effort are within the scope of protection of the present invention.
[0028] The following table describes the abbreviations and key terms in the embodiments of the present invention.
[0029] Example 1 Please see Figure 1 . Figure 1 This is a schematic diagram of the scheduling method for a parallel discrete event simulation engine based on coroutines disclosed in an embodiment of the present invention.
[0030] like Figure 1 As shown in the embodiment of the present invention, a scheduling method for a parallel discrete event simulation engine based on coroutines is disclosed. The method includes: S1. Obtain simulation configuration information; the simulation configuration information includes simulation configuration file, hardware resource parameters, simulation scenario, and several entity data, etc. S2. Initialize the simulation scheduling framework according to the simulation configuration information to obtain a ready-state simulation scheduling framework; the simulation scheduling framework includes an entity coroutine pool, a coroutine scheduler, an event queue, a time manager, a thread pool, and a resource monitor; S3. Process the pending event information input by the user to obtain the pending event queue; S4. The queue of events to be processed is processed using the ready-state simulation scheduling framework to obtain simulation results.
[0031] In another optional embodiment, the initialization of the simulation scheduling framework based on the simulation configuration information to obtain a ready-to-go simulation scheduling framework includes: S21. Obtain entity data information from the simulation configuration information; S22. The entity data information is processed using a preset entity complexity classification calculation model to obtain entity behavior complexity classification information. The expression for the hierarchical calculation model of entity complexity is: in, For entities The complexity of entity behavior, The number of dimensions for entity behavior (such as perception, decision-making, maneuvering, and attack). ≥3), For the first Weights of each behavioral dimension ( ,and ), For entities In the The algorithm scores the complexity of each behavioral dimension (ranging from 0 to 100). This algorithm can accurately quantify the behavioral complexity of different entities and avoid redundancy or insufficiency in stack memory allocation. Entity behavior complexity is used to quantify the overall difficulty of the behavioral dimensions (perception, decision-making, maneuvering, etc.) of a simulated entity. The higher the entity complexity, the higher the computational and data processing volume of the event tasks it undertakes (such as complex path planning and multi-dimensional interaction), which directly determines the basic level of task complexity and conforms to the core logic of complex entities corresponding to complex tasks in simulation scenarios. S23. Using the coroutine stack dynamic allocation calculation model, process the entity behavior complexity classification information to obtain the coroutine stack size information corresponding to the entity. The expression for the dynamic allocation calculation model of the coroutine stack is: in, For entities Corresponding coroutine stack size (unit: KB). Based on the stack coefficients, The value range is 0.5 to 1.2; For entity behavior complexity, Based on the base stack size, The value range is 10-20KB; γ is the high complexity compensation coefficient, with a value range of 0.3-0.8; when the entity complexity exceeds 50, additional stack memory compensation is added to adapt to the behavioral logic requirements of high-complexity entities; the global simulation time is initialized to 0, and the event queue sorting rules and the maximum concurrency of the thread pool are set; at runtime, the coroutine stack is dynamically allocated based on the entity behavior complexity to solve the problem of unreasonable resource allocation caused by the difference in entity behavior complexity. The behavior complexity of different entities is accurately quantified through the entity complexity hierarchical calculation model to avoid redundancy or insufficiency in stack memory allocation; S24. Based on the coroutine stack size information corresponding to the entity, create an entity coroutine pool; during the creation process, the lifecycle, behavioral logic, and state data of each simulation entity are encapsulated as independent coroutines; it should be noted that existing technologies usually use a uniform stack size for all entities, while in this solution, dynamic stack allocation is performed based on the hierarchical nature of entity behavior complexity, thereby optimizing memory usage; S25. Initialize the coroutine scheduler, event queue, time manager, thread pool, and resource monitor; S26. Integrate the entity coroutine pool, coroutine scheduler, event queue, time manager, thread pool, and resource monitor to obtain the ready-to-go simulation scheduling framework.
[0032] It should be noted that the simulation scheduling framework constructed in this embodiment can be referenced in the appendix. Figure 2 The diagram shown illustrates a coroutine scheduling architecture, including the following components: Coroutine scheduler: The core of the simulation engine, responsible for the creation, scheduling, and destruction of coroutines. It adopts cooperative event-driven scheduling to ensure timing determinism. Entity coroutine pool: manages all entity coroutines, realizes coroutine reuse and dynamic stack memory allocation, and adapts to changes in entity size through dynamic expansion algorithm; Event queue: It adopts a priority heap structure and stores events to be processed in order of simulation timestamp to ensure that events are executed in chronological order; Time Manager: Maintains global simulation time, maps logical time to real time, and supports real-time / accelerated simulation; Thread pools: handle computationally intensive tasks, and work with the coroutine scheduler through asynchronous callbacks to avoid blocking the main scheduling loop; Resource monitor: Real-time monitoring of memory, CPU, number of coroutines, and event queue length; dynamically adjusts scheduling strategies to ensure system stability.
[0033] In yet another optional embodiment, the timing of creating the entity coroutine pool includes: S241. Before the engine starts, entities are directly added to the entity mapping via addEntity(). When the engine starts, start() is called in batches to create coroutines. S242. During engine operation, entities are added through the pending_entities_ queue, and start() is called in runStep() to create a coroutine; S243, Snapshot recovery: When restoring an entity from a snapshot, call start(ctx, true) to create a coroutine and maintain the original wake-up time; S244. Establish a 1:1 mapping relationship between coroutines and entities. Each entity corresponds to one coroutine. Each SimEntity object contains a SimTask task_ member variable. Each entity returns a SimTask coroutine through the behavior() pure virtual function.
[0034] It should be noted that the overhead of coroutine creation is significantly lower than that of traditional threads, mainly in the following ways: Memory allocation overhead: Optimized by thread-local lock-free memory pool (GlobalAllocator), hot path allocation time is approximately 50-200 nanoseconds; Coroutine frame initialization: The initialization overhead of a C++20 coroutine state machine is approximately 100-500 nanoseconds; Scheduler registration: The registration overhead for the hierarchical time slot scheduler is approximately 200-800 nanoseconds; Total creation overhead: approximately 0.5-2 microseconds per coroutine.
[0035] In another optional embodiment, the entity coroutine pool uses a coroutine pool hash index reuse algorithm to create an index of coroutines within the coroutine pool; the formula for the coroutine pool hash index reuse algorithm is: in, For the index of coroutines within the pool, Used as a unique identifier for the entity (using a 64-bit string). () represents the hash function (using the SHA-256 hash algorithm). This represents the current total capacity of the coroutine pool. This algorithm enables rapid coroutine location and reuse, reducing the overhead of creation and destruction.
[0036] In another optional embodiment, the entity coroutine pool adopts a dynamic expansion algorithm to dynamically expand its capacity, ensuring that the capacity of the coroutine pool meets the needs of large-scale entity concurrency. The expression for the dynamic expansion algorithm of the coroutine pool is: in, To expand the capacity of the coroutine pool, δ represents the current total capacity of the coroutine pool, and δ is the expansion factor (ranging from 0.2 to 0.5). The number of coroutines currently in use, when Expansion is triggered at certain times.
[0037] In another optional embodiment, the process of processing the user-inputted event information to obtain a queue of events to be processed includes: S31. Collect pending events input by the user; the pending events include entity interaction events, time progression events, external instructions, and internal state update data; S32. Encapsulate the events to be processed to obtain a set of events to be processed; The event to be processed is represented as Event={T,Type,EntityID,Args}, where T is the timestamp, Type is the type, EntityID is the target entity, and Args is the parameter; S33. The set of events to be processed is sorted using the timestamp min-heap sort algorithm to obtain the first event queue; The timestamp of the i-th event in the first event queue satisfy and This ensures that the top of the heap is the earliest executed event. S34. Merge and deduplicate similar events in the first event queue whose timestamp difference is less than a preset time difference threshold to obtain a queue of events to be processed. Specifically: When the timestamp difference of similar events is less than a preset time difference threshold, they are merged into a single event to reduce redundant scheduling. A new event merging weighting algorithm is added to determine the parameters of the merged event. in, The parameters for the merged event. The number of events to be merged. For the first Dynamic priority of events to be merged For the first The parameters of each event to be merged are determined by a weighted average to ensure the accuracy of the event information.
[0038] In another optional embodiment, the timestamp min-heap sort algorithm uses an event priority dynamic adjustment model to calculate event priority values, and sorts the set of events to be processed in order according to the calculated priority values. The expression for the event priority dynamic adjustment model is: in, This represents the dynamic priority of the event, with a value ranging from 0 to 10. This is the time weight, with a value ranging from 0.4 to 0.6; is the entity importance weight, ranging from 0.4 to 0.6; T is the event timestamp. This is the current global simulation time; To find the minimum value, avoid a denominator of 0. ; The importance score of the target entity is given, with a value ranging from 1 to 5.
[0039] In another optional embodiment, the step of processing the queue of events to be processed using the ready-state simulation scheduling framework to obtain simulation results includes: S41. The coroutine scheduler retrieves the top event from the queue of events to be processed, and obtains the current event and the target entity ID; S42. Update the global simulation time to the timestamp of the current event; S43. Locate and wake up the corresponding coroutine for the current event based on the target entity ID; S44. Determine the task type of the current event to obtain the task type; the task type is either a logic-intensive task or a computation-intensive task. If the task type is a logic-intensive task, then proceed to step S45; If the task type is a computationally intensive task, then proceed to step S46; It should be noted that this solution does not use completely consistent processing logic for logic-intensive tasks and computation-intensive tasks. Instead, it performs more granular classification processing based on task type and computational intensity. By introducing a hybrid scheduling of coroutines and thread pools, logic-intensive tasks use coroutines and computation-intensive tasks use thread pools, instead of using only a single scheduling mode, which improves processing efficiency. S45. The ready-state simulation scheduling framework processes the current event as a logic-intensive task, and executes step S47 after the processing is completed. S46. The ready-state simulation scheduling framework processes the current event as a computationally intensive task, and executes step S47 after the processing is completed. S47. Determine whether the simulation time has reached the end condition or a stop command has been received, and obtain the second judgment result; If the second judgment result is yes, exit the main loop and execute step S48; If the second judgment result is negative, proceed to step S41; S48. The system outputs the simulation results to the subsequent analysis or visualization process and performs resource release.
[0040] It should be noted that the embodiments of the present invention use a hybrid scheduling mechanism, employing coroutines for logic-intensive tasks and thread pools for computation-intensive tasks, thus balancing concurrency efficiency and computational performance to solve the scheduling efficiency problem of different types of tasks.
[0041] In yet another optional embodiment, the method further includes evaluating the simulation performance using a simulation performance evaluation model to obtain a simulation system performance evaluation value; The expression for the simulation performance evaluation model is as follows: in, These are the performance evaluation values for the simulation system. The total number of simulated entities, The total number of events processed. This represents the total simulation time. Average CPU utilization This algorithm, which measures average memory usage, can quantitatively evaluate the concurrency capabilities and resource utilization efficiency of a simulation system, providing a basis for system optimization.
[0042] In yet another optional embodiment, determining the task type of the current event to obtain the task type includes: S441. Calculate the overall task complexity of the current event using the task complexity calculation model; The calculation method for the task complexity calculation model is as follows: in, For the current event The overall task complexity is given by λ, which is the computational weight and ranges from 0.6 to 0.8. The number of calculation cycles required for the task (in millions). The algorithm comprehensively evaluates the computational and data processing pressure of a task by measuring the amount of data processed (in MB), providing a more accurate basis for task classification. S442. Based on the overall task complexity of the current event, the computational density determination model is used to calculate and obtain the computational density value of the current event. The expression for the computational density determination model is: in, For the current event The computational density value, For the overall complexity of the task, This is the time slice for coroutine execution; the default value is 100μs. This is a hardware performance coefficient, dynamically adjusted based on the CPU clock speed, with a value ranging from 0.8 to 1.2. S443. If the computational density value of the current event is greater than the preset density threshold, the task type of the current event is set to a logic-intensive task; otherwise, it is set to a computation-intensive task.
[0043] In another optional embodiment, the ready-to-go simulation scheduling framework processes the current event as a logic-intensive task, and after processing, executes step S47, including: S451. The legality of the coroutine corresponding to the current event is judged (excluding destroyed and abnormal coroutines), and a first judgment result is obtained; If the first judgment result is negative, proceed to step S41; When the first judgment result is yes, step S452 is executed; S452. The coroutine corresponding to the current event is executed in user mode to process logic without kernel mode switching, updating the entity state and generating subsequent events. The entity state update uses a state fusion algorithm: in, For the updated entity state, Historical state weights (values ranging from 0.3 to 0.5). The entity is in its old state. The state update amount generated by this logical processing is used to achieve a smooth transition of entity state and avoid abrupt state changes. S453, The coroutine corresponding to the current event calls yield to relinquish CPU execution rights, saves the context, and switches to a suspended state; S454. The ready-to-go simulation scheduling framework writes the latest entity state into shared memory, submits subsequent events to the event queue to be processed, and transfers control to the coroutine scheduler, executing step S47.
[0044] It should be noted that the processing flow for logic-intensive tasks can be found in the appendix. Figure 4 .
[0045] In yet another optional embodiment, the hierarchical time slot scheduler employs a hierarchical time slot scheduling process to manage the suspension and resumption of coroutines; the hierarchical time slot scheduling process includes: 1) When a coroutine is suspended, the wake-up time is calculated in SleepAwaiter::await_suspend(); 2) Add the coroutine handle to the corresponding slot of the hierarchical time slot according to the wake-up time; 3) When the hierarchical time slot scheduler advances, it checks the due coroutines in the current slot through a cascading check mechanism; 4) Collect expired coroutine handles into the ready_events vector; 5) Batch resume execution in Worker::runStep(): for (auto h : ready_events)h.resume().
[0046] It should be noted that this scheme employs a hierarchical time slot algorithm, which offers several advantages: • O(1) scheduling complexity, which is more efficient than the O(log N) scheduling complexity of priority queues; • Supports batch recovery, reducing function call overhead; • To avoid the “thundering herd effect,” the start time of batch entity creation is randomly delayed by initiating phase scattering technology; • The hierarchical cascading mechanism supports time span management from microseconds to hours.
[0047] In yet another optional embodiment, the suspension timing of the system management coroutine includes: • Active suspension (time-driven): The entity calls co_await wait() to wait for a specified time; • Passive suspension (event-driven): The coroutine ends when the entity is destroyed by calling co_return.
[0048] As an optional implementation, in the first aspect of the present invention, the recovery timing of the system management coroutine includes: • Time Expiration Recovery: Recover expired coroutines when the layered time slots advance; • Message-triggered recovery: System messages or entity messages trigger immediate recovery.
[0049] In another optional embodiment, the system employs a cooperative event-driven scheduling mechanism to ensure that events are executed in chronological order, guaranteeing the determinism and reproducibility of the simulation timing. Specifically: The coroutine scheduler retrieves the top event (with the smallest timestamp) from the queue of pending events. Update the global simulation time to the timestamp of the current event; Locate and activate the corresponding coroutine based on the target entity ID; After a goroutine finishes processing the current event, it voluntarily relinquishes execution control. The coroutine scheduler continues processing the next event.
[0050] In yet another alternative embodiment, the system destroys the coroutine in the following scenarios: • Entity destruction is triggered by: damage, fuel depletion, or mission completion; • Coroutine terminates naturally: entity is in a dead state or near-death state; • Exception handling: EntityDestroyedException causes the coroutine to exit gracefully; • Destruction and destruction: The SimTask destructor automatically destroys the coroutine handle.
[0051] The following is an optional implementation method in which the system destroys coroutines and reclaims resources in the following scenarios: • Damage: Call destroy(ctx) when HP ≤ 0; • Fuel depleted: Call destroy(ctx) when fuel ≤ 0; • Mission complete: The missile hits the target; destroy(ctx) is called when the mission ends. • Logical deletion: Manually call destroy(); • Logical deletion: Manually call destroy(); • Entity death state: When EntityLifeState::DEAD, simply use co_return; • Entity in dying state: after setting destroyed_=true during EntityLifeState::DYING, co_return; • Entity in dying state: after setting destroyed_=true during EntityLifeState::DYING, co_return; • EntityDestroyedException: Check the entity's state in await_resume(), and throw an exception if the entity has been destroyed; • Exception handling: Catch exceptions and exit gracefully in promise_type::unhandled_exception(); • Exception handling: Catch exceptions and exit gracefully in promise_type::unhandled_exception(); • SimTask destructor: ~SimTask() { if (handle_) handle_.destroy();}; • Move semantics: The original handle is destroyed in the move assignment operator; • Move semantics: The original handle is destroyed in the move assignment operator; The destruction process includes: • Publish the ENTITY_DESTROYED event to notify external systems; • Cancel unexpired schedules from the hierarchical time slot scheduler; • Remove entity references from the spatial index; • Remove all associated data from the component pool; • The memory allocator reclaims coroutine frame memory.
[0052] In another optional embodiment, the ready-to-go simulation scheduling framework processes the current event as a computationally intensive task, and after processing, executes step S47, including: S461. The coroutine corresponding to the current event encapsulates the computation task into an asynchronous task, binds the coroutine ID, actively suspends the task, and saves the coroutine context. S462. The coroutine scheduler submits the asynchronous task to the thread pool; Specifically: Threads are allocated according to the minimum load thread allocation algorithm, and thread load prediction algorithm is used to avoid thread overload in advance; (1) Thread load prediction algorithm: in, This represents the predicted future load value for the thread. The current load of the thread. This represents the number of tasks waiting to be processed in the thread's queue. For the first The overall complexity of each pending task. This is the load conversion factor (ranging from 0.1 to 0.3), which predicts the future load on threads and avoids assigning tasks to threads that are about to become overloaded.
[0053] (2) Minimum Load Thread Allocation Algorithm: in, Formula for calculating thread load: in, This is the length of the task queue for this thread. Weighted by runtime (0.3–0.6). This indicates the running time of the current task in this thread, ensuring the reasonableness of the load assessment.
[0054] S463: The thread pool executes computational tasks (path planning, collision detection, firepower calculation, etc.) in parallel to obtain the computation results; S464. The coroutine scheduler wakes up the coroutine and restores its context, merges the computation results into the entity state, and the coroutine continues to execute subsequent logic. The computation result fusion uses a weighted fusion algorithm. in, The final state of the merged entity is represented by β, which is the state weight when the coroutine is suspended (ranging from 0.4 to 0.6). This refers to the entity state when the coroutine is suspended. For the calculation results of the thread pool, ensure that the calculation results are reasonably integrated with the entity state; S465. Update thread pool utilization, clean up temporary resources, complete hybrid scheduling and return control. Thread pool utilization calculation and dynamic adjustment algorithm: Wherein, ThreadPoolUsage is the thread pool utilization rate, ActiveThreads is the current number of active threads, TotalThreads is the current total number of threads in the thread pool, and NewTotalThreads is the adjusted total number of threads in the thread pool. Adjust the number of threads (default 2-4) using this algorithm to adaptively adjust the thread pool capacity, balancing computational performance and resource consumption; Memory management optimization: • Memory allocation is performed using GlobalAllocator, supporting 16-byte alignment to meet SIMD requirements; • Memory pool strategy: ≤1KB uses thread-local lock-free memory pool, >1KB uses system heap; • Small and large bins (16B-1024B) reduce memory fragmentation; • Thread-local allocation avoids false sharing and lock contention; S466. After the event is processed, the coroutine voluntarily relinquishes its execution right, the coroutine scheduler updates the global simulation time, and executes step S47.
[0055] It should be noted that the computationally intensive task processing method employs a cooperative scheduling approach using threads and coroutines. The flowchart of this cooperative scheduling method can be found in the appendix. Figure 3 , attached Figure 3 A cooperative scheduling flowchart is provided, with appendix. Figure 5 A performance comparison chart between coroutines and threads is presented.
[0056] Example 2 Please see Figure 6 . Figure 6 This invention discloses a schematic diagram of a scheduling device for a parallel discrete event simulation engine based on coroutines.
[0057] like Figure 6 As shown in the figure, an embodiment of the present invention discloses a scheduling device for a parallel discrete event simulation engine based on coroutines, the device comprising: The simulation configuration information acquisition module 201 is used to acquire the simulation configuration information input by the user; the simulation configuration information includes simulation configuration files, hardware resource parameters, simulation scenarios, and several entity data, etc. The simulation scheduling framework initialization module 202 is used to initialize the simulation scheduling framework according to the simulation configuration information to obtain a ready-state simulation scheduling framework; the simulation scheduling framework includes an entity coroutine pool, a coroutine scheduler, an event queue, a time manager, a thread pool, and a hierarchical time slot scheduler; The event queue generation module 203 is used to process the pending event information input by the user to obtain a pending event queue; The event processing module 204 uses the ready-state simulation scheduling framework to process the queue of events to be processed and obtain simulation results.
[0058] This second embodiment is the product embodiment corresponding to the first embodiment. The steps and methods included are the same as those in the first embodiment, and will not be described in detail in the second embodiment.
[0059] Example 3 This third embodiment presents a comparison of the effects of traditional technical solutions and the solution of the present invention in the implementation of a large-scale simulation system.
[0060] In this embodiment, the simulation system needs to coordinate the concurrent operation of tens of thousands of simulation entities.
[0061] When using a traditional multithreaded approach: • Thread creation overhead is large (1-10 microseconds / thread); • High memory usage (1-8MB / thread); • Limited concurrency (typically <1000 threads); • Scheduling uncertainties lead to unreproducible simulation results.
[0062] When using the method of the present invention: • Low overhead for coroutine creation (100-350 nanoseconds / coroutine); • Small memory footprint (128-512 bytes / coroutine frame, 16-64KB coroutine stack). • Supports millions of concurrent connections (maximum number of entities: 2,000,000 coroutines); • Layered time slot scheduling guarantees O(1) complexity for coroutine wake-up; • Cooperative scheduling ensures that simulation results are reproducible; • Hybrid scheduling balances logical processing and computational performance.
[0063] Example 4 This fourth embodiment illustrates the mapping between code and documentation evidence in the process of implementing the method provided in this invention. This embodiment retains only runtime and production-side evidence directly related to the main innovation of this case; filenames are only specified down to the filename and extension.
[0064] 4.1 Evidence for Entity Complexity Hierarchical Calculation This excerpt demonstrates that the runtime classifies entities based on their behavioral dimensions when creating them, laying the foundation for subsequent coroutine stack allocation.
[0065] ```cpp / / SimEntity class definition in e3_entity.h class E3_API SimEntity { public: SimEntity(SimContext ctx, EntityID id, std::string name); virtual ~SimEntity() = default; bool initFromArchetype(SimContext ctx, const std::string archetype_id); void setDynamicSpawn(bool val) { is_dynamic_spawn_ = val;} EntityID id() const { return id_;} const std::string name() const { return name_;} / / ========================================================== virtual SimTask behavior(SimContext ctx) = 0; / / Main logic implementation (behavior tree / finite state machine) virtual void onSectorChanged(uint64_t old_cell, uint64_t new_cell) {} / / The physical space location changes to another sector virtual void onMsg(SimContext ctx, const Message msg) = 0; / / Process the received simulation message virtual void spawnParasiteUnits(SimContext ctx, const Archetype arc) = 0; / / ========================================================== SleepAwaiter wait(SimContext ctx, TimePoint duration, Priority p =Priority::NORMAL); SleepAwaiter wait_seconds(SimContext ctx, double sec, Priority p =Priority::NORMAL); void addSensor(SimContext ctx, const std::string id, SensorTypetype, SensorCategory category, double range, double interval = 2.0); void setWorkerID(int wid) { worker_id_ = wid;} int getWorkerID() const { return worker_id_;} / / Query nearby entities std::vector <entityid>getNeighbors(SimContext ctx, doubleradius); bool isDestroyed() const { return destroyed_;} void destroy(SimContext ctx); void configureMotion(SimContext ctx, const std::string new_solver_name = "", double threshold = -1.0, double max_speed = -1.0); Vec3 getPosition(SimContext ctx) const; Vec3 getVelocity(SimContext ctx) const; void setKinematics(SimContext ctx, const Vec3 pos, const Vec3 vel); void setGeoPosition(SimContext ctx, double lat, double lon,double alt); GeoPos getGeoPosition(SimContext ctx) const; double distanceTo(SimContext ctx, EntityID target_id) const; double distanceTo(SimContext ctx, const Vec3 target_pos) const; / / === Serialization Interface === / / 1. Save / Load Basic Data template<class Archive> void serialize(Archive ar) { ar(id_, name_, next_wake_time_, worker_id_, destroyed_,rand_); } private: void start(SimContext ctx, bool is_restore = false); / / Internal engine call friend class Worker; protected: EntityID id_; std::string name_; TimePoint next_wake_time_ = 0; SimTask task_{nullptr}; Random rand_; public: Random getRandom() { return rand_;} protected: int worker_id_ = -1; bool is_restoring_ = false; / / Transient variable, not serialized bool is_dynamic_spawn_ = false; / / Marks whether the entity is dynamically generated. bool destroyed_ = false; friend class SleepAwaiter; SimEntity() = default; / / Cereal requires a default constructor }; ``` 4.2 Evidence for Dynamic Allocation of Process Stack This snippet demonstrates that the runtime dynamically allocates the coroutine stack size based on the entity's complexity, avoiding memory issues caused by uniform allocation.
[0066] ```cpp / / Global memory allocator in e3_memory.h class E3_API GlobalAllocator { public: / / Get the singleton (actually, this is just for API compatibility; internally it's a static method) static GlobalAllocator instance() { static GlobalAllocator g; return g; } / / Allocate memory void alloc(size_t size) { / / If the size is too large, use the system heap (slow path) directly. if (size>memory::MAX_POOL_SIZE) { return ::operator new(size); } / / [Key] Obtain the TLS Context of the current thread / / static thread_local means that each thread has its own independent copy of tls_ctx static thread_local memory::TLSContext tls_ctx; / / Allocate from a thread-private pool, lock-free throughout. return tls_ctx.getPool(size).allocate(); } / / Release memory void free(void ptr, size_t size) { if (!ptr) return; if (size>memory::MAX_POOL_SIZE) { ::operator delete(ptr); return; } / / Similarly, obtain the TLS Context of the current thread. static thread_local memory::TLSContext tls_ctx; / / Release back to thread-private Pool tls_ctx.getPool(size).deallocate(ptr); } }; ``` 4.3 Evidence for Hierarchical Time Slot Scheduling This fragment shows that the runtime uses a hierarchical time slot scheduling algorithm to manage coroutine wake-ups, achieving scheduling with O(1) complexity.
[0067] ```cpp / / Hierarchical time slot scheduler advancement void TimingWheel::tick(DataManager dm, std::vector <std::coroutine_handle<> > out_events, uint64_t step_us) { auto pool = dm.scheduler_data; / / Process the cache for (int p = 0; p<7; ++p) { if (!expired_buffer_[p].empty()) { out_events.insert(out_events.end(), expired_buffer_[p].begin(), expired_buffer_[p].end()); expired_buffer_[p].clear(); } } / / Calculate how many steps are needed uint64_t steps = step_us / tick_us_; for (uint64_t i = 0; i <steps; ++i) { current_time_ += tick_us_; uint64_t current_tick_idx = current_time_ / tick_us_; / / Cascading inspection mechanism for (int level = 0; level <LEVEL_COUNT; ++level) { int slot = (current_tick_idx>>(8 level)) SLOT_MASK; process_slot(dm, out_events, level, slot); if (slot != 0) break; } } } ``` 4.4 Coroutine Creation Evidence This fragment shows that the runtime creates coroutines at multiple times and establishes a coroutine-entity 1:1 mapping.
[0068] ```cpp void SimEntity::start(SimContext ctx, bool is_restore) { is_restoring_ = is_restore; / / Mark the start task_ = behavior(ctx); / / Create a coroutine task_.resume(); / / Execute until the first co_await is_restoring_ = false; / / End of marker if (is_restore next_wake_time > 0) { TimePoint now_time = ctx.engine.now(); if (next_wake_time_>now_time) { / / Retain the original wake-up time in recovery mode } } } ``` 4.5 Evidence of Cooperative Scheduling This excerpt indicates that a cooperative scheduling mechanism is used at runtime, where a coroutine voluntarily relinquishes execution rights after processing an event.
[0069] ```cpp / / 4. Time Wheel Scheduling uint64_t step_us = target_time - current_time_; if (step_us>0) { std::vector <std::coroutine_handle<> >ready_events; ready_events.reserve(256); timing_wheel_.tick(ctx_->data, ready_events, step_us); current_time_ = target_time; for (auto h : ready_events) { if (h !h.done()) h.resume(); } } ``` 4.6 Coroutine Exception Handling This excerpt indicates that when a destruction exception occurs during coroutine execution, the exception handling mechanism is triggered to quietly terminate the coroutine.
[0070] ```cpp void SimTask::promise_type::unhandled_exception() { try { std::rethrow_exception(std::current_exception()); } catch (const EntityDestroyedException ) { / / The entity is destroyed, the coroutine exits gracefully, and no logs are created. } catch (const std::exception e) { E3_LOG_ERROR("[Coroutine]Exception caught in entity behavior:{}", e.what()); } catch (...) { E3_LOG_ERROR("[Coroutine]Unknown exception caught!"); } / / Here you can add logic: for example, notifying the Engine to mark the entity as damaged. } ``` 4.7 Coroutine Destruction of Evidence This snippet shows that the runtime triggers coroutine destruction and cleans up related resources when the entity is destroyed.
[0071] ```cpp / / Entity Destruction - Actual Implementation void SimEntity::destroy(SimContext ctx) { if (!destroyed_) { destroyed_ = true; / / Publish destruction event auto evt = e3::SimEvent::create(e3::EventTypes::ENTITY_DESTROYED, id_); evt.sim_time = ctx.engine.now() / 1000000.0; ctx.events.publish(evt); / / Get the current Worker and destroy it if (auto w = Engine::getCurrentWorker()) { w->destroyEntity(id_); } } } ``` 4.8 Performance Monitoring Evidence This excerpt demonstrates that the system monitors performance at runtime and dynamically adjusts resource allocation.
[0072] ```cpp / / PerformanceMonitor class in e3_stats.h class PerformanceMonitor { public: void recordStepStart() { step_start_ = std::chrono::steady_clock::now(); } void recordStepEnd(SimStats stats) { auto now = std::chrono::steady_clock::now(); double duration = std::chrono::duration<double, std::milli>(now - step_start_).count(); stats.frame_count++; / / Simple exponential moving average if (stats.avg_step_wall_time_ms == 0.0) stats.avg_step_wall_time_ms = duration; else stats.avg_step_wall_time_ms = stats.avg_step_wall_time_ms 0.95 + duration 0.05; if (duration>stats.max_step_wall_time_ms) stats.max_step_wall_time_ms = duration; } private: std::chrono::steady_clock::time_point step_start_; }.
[0073] The system embodiments described above are merely illustrative. The modules described as separate components may or may not be physically separate, and the components shown as modules may or may not be physical modules; that is, they may be located in one place or distributed across multiple network modules. Some or all of the modules can be selected to achieve the purpose of this embodiment according to actual needs. Those skilled in the art can understand and implement this without any creative effort.
[0074] Through the detailed description of the above embodiments, those skilled in the art can clearly understand that each implementation method can be implemented by means of software plus necessary general-purpose hardware platforms, and of course, it can also be implemented by hardware. Based on this understanding, the above technical solutions, in essence or the part that contributes to the prior art, can be embodied in the form of a software product. This computer software product can be stored in a computer-readable storage medium, including read-only memory (ROM), random access memory (RAM), programmable read-only memory (PROM), erasable programmable read-only memory (EPROM), one-time programmable read-only memory (OTPROM), electrically-erasable programmable read-only memory (EEPROM), compact disc read-only memory (CD-ROM) or other optical disc storage, disk storage, magnetic tape storage, or any other computer-readable medium that can be used to carry or store data.
[0075] Finally, it should be noted that the scheduling method and apparatus for a parallel discrete event simulation engine based on coroutines disclosed in the embodiments of the present invention are merely preferred embodiments of the present invention and are only used to illustrate the technical solutions of the present invention, not to limit it. Although the present invention has been described in detail with reference to the foregoing embodiments, those skilled in the art should understand that modifications can still be made to the technical solutions described in the foregoing embodiments, or equivalent substitutions can be made to some of the technical features. Such modifications or substitutions do not cause the essence of the corresponding technical solutions to deviate from the spirit and scope of the technical solutions of the embodiments of the present invention.< / entityid>
Claims
1. A scheduling method for a parallel discrete event simulation engine based on coroutines, characterized in that, The method includes: S1. Obtain simulation configuration information; the simulation configuration information includes simulation configuration file, hardware resource parameters, simulation scenario and several entity data; S2. Initialize the simulation scheduling framework according to the simulation configuration information to obtain a ready-state simulation scheduling framework; the simulation scheduling framework includes an entity coroutine pool, a coroutine scheduler, an event queue, a time manager, a thread pool, and a hierarchical time slot scheduler; S3. Process the pending event information input by the user to obtain the pending event queue; S4. The queue of events to be processed is processed using the ready-state simulation scheduling framework to obtain simulation results.
2. The scheduling method for a parallel discrete event simulation engine based on coroutines according to claim 1, characterized in that, The initialization of the simulation scheduling framework based on the simulation configuration information to obtain a ready-state simulation scheduling framework includes: S21. Obtain entity data information from the simulation configuration information; S22. The entity data information is processed using a preset entity complexity classification calculation model to obtain entity behavior complexity classification information. The expression for the hierarchical calculation model of entity complexity is: in, For entities The complexity of entity behavior, The number of entity behavior dimensions. For the first The weights of each behavioral dimension For entities In the Complexity score for each behavioral dimension; S23. Process the entity behavior complexity classification information to obtain the coroutine stack size information corresponding to the entity. S24. Create an entity coroutine pool based on the coroutine stack size information corresponding to the entity; S25. Initialize the coroutine scheduler, event queue, time manager, thread pool, and hierarchical time slot scheduler; S26. Integrate the entity coroutine pool, coroutine scheduler, event queue, time manager, thread pool, and hierarchical time slot scheduler to obtain the ready-state simulation scheduling framework.
3. The scheduling method for a parallel discrete event simulation engine based on coroutines according to claim 1, characterized in that, The process of processing the user-inputted event information to obtain a queue of events to be processed includes: S31. Collect pending events input by the user; the pending events include entity interaction events, time progression events, external instructions, and internal state update data; S32. Encapsulate the events to be processed to obtain a set of events to be processed; S33. The set of events to be processed is sorted using the timestamp min-heap sort algorithm to obtain the first event queue; S34. Merge and deduplicate similar events in the first event queue whose timestamp difference is less than a preset time difference threshold to obtain a queue of events to be processed.
4. The scheduling method for a parallel discrete event simulation engine based on coroutines according to claim 3, characterized in that, The timestamp min-heap sort algorithm uses an event priority dynamic adjustment model to calculate event priority values, and sorts the set of events to be processed in order according to the calculated priority values. The expression for the event priority dynamic adjustment model is: in, This refers to the dynamic priority of events. Time weighting; As the importance weight of the entity; For event timestamps, This is the current global simulation time; This is a local minimum value, used to avoid the denominator being 0; Score the importance of the target entity.
5. The scheduling method for a parallel discrete event simulation engine based on coroutines according to claim 1, characterized in that, The process of using the ready-state simulation scheduling framework to process the queue of events to be processed and obtaining simulation results includes: S41. The coroutine scheduler retrieves the top event from the queue of events to be processed, and obtains the current event and the target entity ID; S42. Update the global simulation time to the timestamp of the current event; S43. Locate and wake up the corresponding coroutine for the current event based on the target entity ID; S44. Determine the task type of the current event to obtain the task type; the task type is either a logic-intensive task or a computation-intensive task. If the task type is a logic-intensive task, then proceed to step S45; If the task type is a computationally intensive task, then proceed to step S46; S45. The ready-state simulation scheduling framework processes the current event as a logic-intensive task, and executes step S47 after the processing is completed. S46. The ready-state simulation scheduling framework processes the current event as a computationally intensive task, and executes step S47 after the processing is completed. S47. Determine whether the simulation time has reached the end condition or a stop command has been received, and obtain the second judgment result; If the second judgment result is yes, exit the main loop and execute step S48; If the second judgment result is negative, proceed to step S41; S48. Perform resource release and obtain simulation results.
6. The scheduling method for a parallel discrete event simulation engine based on coroutines according to claim 5, characterized in that, The step of determining the task type of the current event to obtain the task type includes: S441. Calculate the overall task complexity of the current event using the task complexity calculation model; The calculation method for the task complexity calculation model is as follows: in, For the current event The overall task complexity is given by λ, where λ is the computational weight. Calculate the number of cycles required for the task. The amount of data processed by the task; S442. Based on the overall task complexity of the current event, the computational density determination model is used to calculate and obtain the computational density value of the current event. The expression for the computational density determination model is: in, For the current event The computational density value, For the overall complexity of the task, For coroutine execution time slices, This refers to the hardware performance coefficient. S443. If the computational density value of the current event is greater than the preset density threshold, the task type of the current event is set to a logic-intensive task; otherwise, it is set to a computation-intensive task.
7. The scheduling method for a parallel discrete event simulation engine based on coroutines according to claim 5, characterized in that, The ready-state simulation scheduling framework processes the current event as a logic-intensive task, and after processing, executes step S47, including: S451. The legality of the coroutine corresponding to the current event is judged to obtain a first judgment result; If the first judgment result is negative, proceed to step S41; When the first judgment result is yes, step S452 is executed; S452. The coroutine corresponding to the current event is executed in user mode to process logic without kernel mode switching, updating the entity state and generating subsequent events. S453, The coroutine corresponding to the current event calls yield to relinquish CPU execution rights, saves the context, and switches to a suspended state; S454. The ready-to-go simulation scheduling framework writes the latest entity state into shared memory, submits subsequent events to the event queue to be processed, and transfers control to the coroutine scheduler, executing step S47.
8. The scheduling method for a parallel discrete event simulation engine based on coroutines according to claim 5, characterized in that, The ready-state simulation scheduling framework processes the current event as a computationally intensive task, and after processing, executes step S47, including: S461. The coroutine corresponding to the current event encapsulates the computation task into an asynchronous task, binds the coroutine ID, actively suspends the task, and saves the coroutine context. S462. The coroutine scheduler submits the asynchronous task to the thread pool; S463. The thread pool executes computation tasks in parallel to obtain computation results; S464. The coroutine scheduler wakes up the coroutine and restores the coroutine context, merges the calculation results into the entity state, and the coroutine continues to execute subsequent logic. S465, Update thread pool utilization, clean up temporary resources, complete hybrid scheduling and return control; S466. After the event is processed, the coroutine voluntarily relinquishes its execution right, the coroutine scheduler updates the global simulation time, and executes step S47.
9. The scheduling method for a parallel discrete event simulation engine based on coroutines according to claim 2, characterized in that, The hierarchical time slot scheduler uses a hierarchical time slot scheduling process to manage the suspension and resumption of coroutines; The hierarchical time slot scheduling process includes: When a coroutine is suspended, the wake-up time is calculated and added to the corresponding level of the hierarchical time slot; As time progresses, expired coroutine handles are collected into the ready_events vector through a cascading check mechanism; Batch resume execution of expired coroutines to reduce function call overhead.
10. A scheduling device for a parallel discrete event simulation engine based on coroutines, characterized in that, The apparatus for implementing the scheduling method of a parallel discrete event simulation engine based on coroutines as described in any one of claims 1-9 includes: The simulation configuration information acquisition module is used to acquire the simulation configuration information input by the user; the simulation configuration information includes simulation configuration files, hardware resource parameters, simulation scenarios, and several entity data, etc. The simulation scheduling framework initialization module is used to initialize the simulation scheduling framework according to the simulation configuration information to obtain a ready-state simulation scheduling framework; the simulation scheduling framework includes an entity coroutine pool, a coroutine scheduler, an event queue, a time manager, a thread pool, and a hierarchical time slot scheduler; The event queue generation module is used to process the user-input event information to obtain the event queue. The event processing module uses the ready-state simulation scheduling framework to process the queue of events to be processed and obtain simulation results.