A portion of the disclosure of this patent document contains material that is subject to copyright protection. The copyright owner has no objection to the facsimile reproduction by anyone of the patent disclosure, as it appears in the Patent and Trademark Office patent files or records, but otherwise reserves all copyright rights whatsoever.
The present invention relates generally to an efficient processor core operation, and more particularly, to a command system to efficiently use memory cache of a processor unit.
Current processing systems have multiple processing cores to provide parallel processing of computational tasks, which increases the speed of completing such tasks. In multi-core systems, it is desirable to perform multi-threading in order to accomplish parallel processing of programs. Multi-threading is a widespread programming and execution model that allows multiple software threads to exist within the context of a single process. These software threads share the resources of the multi-core system, but are able to execute independently. Multi-threading can also be applied to a single process to enable parallel execution on a multi-core system. This advantage of a multi-threaded program allows it to operate faster on computer systems that have multiple CPUs, CPUs with multiple cores, or across a cluster of machines because the threads of the program naturally lend themselves to concurrent execution.
However, programs executed over multiple cores are limited by the processing speed of the processing cores as well as any conflicts over shared resources such as external memory in the form of RAM. Processing cores such as CPUs typically include high speed internal memory, termed cache memory, which is used to speed up access to data and instructions used by the CPU. Memory caches save computationally expensive reads to RAM. Memory caches typically function by loading data that may be next used by the CPU. Whether data stored in the cache is useful to the CPU is sometimes random, as the CPU will first look to needed data in the cache and then in RAM.
Memory latency, which is the length of time between the receipt of a read request and its release of data corresponding with the request, is a key consideration of any software program that attempts to run in an efficient manner. In a multi-threaded environment this consideration is even more critical since the more threads that are running, the greater the likelihood that this latency will effect overall performance. This is especially true in the case where two different threads are attempting to write and/or read from a shared memory location in RAM. This latency is a critical factor when considering the run time cost of transferring state data from one location in program memory to another.
CPU memory cache efficiency is another important consideration. As explained above, the cache memory is a fast, but extremely limited, local memory storage for a processor. Data from external memory is copied into the CPU cache for two main purposes. One is to provide the memory for the actual CPU instructions that are to be executed. This is commonly referred to as the instruction cache. The other cache is commonly referred to as the program data cache. The program data cache is where the program state data that instructions are paired with is stored. While various CPUs may handle the memory cache differently, there is a uniform issue in that the instruction cache and the data cache are an extremely limited resource. Due to this, it is extremely important to utilize these caches in an efficient manner. In addition to being an extremely limited resource, the performance of both the instruction cache and the data cache is gated by how fast the processor can transfer data from main memory into the cache for use by the processor. In this way, the performance of a software program is tied to both efficient instruction cache utilization and data cache utilization, as well as, the latency inherent in updating these resources. To efficiently communicate or transfer data and commands within a multi-threaded program it is desirable to minimize the required updates to the instruction cache and the data cache.
Thus, there is a need for defining an efficient framework for communicating program state and commands to various functions from a program executed by a processing unit by minimizing required updates to the instruction cache and data cache. There is a further need for a command module to bind delegates from a program to data in the form of payloads for later access for efficient processor execution using the data. There is a further need for a command module which allows necessary resources to be accessible in the cache when program delegates are loaded.
According to one example, a processing system for efficient execution of program functions is disclosed. The system includes a processor unit including a processor and cache memory. An external memory is coupled to the processing unit. The external memory includes a payload repository including one repository buffer. A direct command module loads a payload in the payload repository and binds the payload with a program delegate to flush the payload from the cache memory when the associated program delegate is to be executed by the processing unit, bypassing accesses to the cache memory.
Another example is a method for efficiently executing a delegate of a program by a processor unit coupled to an external memory. A payload is bound with a program delegate. The payload is associated with the delegate via a payload identifier. The payload is pushed to a repository buffer in the external memory. The payload is flushed by reading the payload identifier and loading the payload from the repository buffer. The delegate is executed using the loaded payload.
Another example is a non-transitory, machine-readable medium having stored thereon instructions for executing a delegate from a program. The stored instructions comprise machine executable code, which when executed by at least one machine processor, causes the machine processor to bind a payload with a program delegate. The instructions cause the machine processor to map the payload with the delegate via a payload identifier. The instructions cause the machine processor to push the payload to a repository buffer in the external memory. The instructions cause the machine processor to flush the payload by reading the payload identifier and loading the payload from the repository buffer. The instructions cause the machine processor to execute the delegate using the loaded payload.
Additional aspects of the invention will be apparent to those of ordinary skill in the art in view of the detailed description of various embodiments, which is made with reference to the drawings, a brief description of which is provided below.
While the invention is susceptible to various modifications and alternative forms, specific embodiments have been shown by way of example in the drawings and will be described in detail herein. It should be understood, however, that the invention is not intended to be limited to the particular forms disclosed. Rather, the invention is to cover all modifications, equivalents, and alternatives falling within the spirit and scope of the invention as defined by the appended claims.
The multi-core processing system 100 executes a program by distributing the tasks or functions in the program among worker threads associated with the processor units 102, 104, and 106.
A command system 130 provides an interface with the common external memory 110. As will be explained, the command system 130 allows the efficient use of internal cache memory by minimizing memory transfer based on calls to program functions made by the processor unit 102. This system facilitates the efficient transfer and distribution of program state data and related commands within a processor unit such as the processor unit 102 of a multi-core system 100 in
As shown in
The direct and indirect modules of the command system 130 access a payload repository area 140, which resides in an area of the external memory 110. The payload repository area 140 serves as storage for data payloads that are used by the command modules 132 and 134 to be loaded into the cache memory 122 based on user functions. The payload repository area 140 includes multiple payload repositories for each direct and indirect command module. In this example, the payload repository area 140 includes an indirect payload repository 142 and direct payload repositories 144, 146, and 148. The indirect payload repository 142 stores payloads of data required by the indirect command module 134. Each direct module such as the direct command modules 132 and 138 have a corresponding direct payload repository such as payload repositories 144 and 146 to store payloads of data. The payloads of data are used by functions of programs when executed by the processor unit 102.
The external memory 110 also stores programs for execution by the system 100. An example of such a program is a program 150 that includes various program functions that are executed by a processor unit or units in the system 100. The program functions are referenced as delegates as their execution is deferred. The program functions typically require access to commands and state data to be executed on one of the processor units such as the processor unit 102. As explained above, the time to access such commands and state data influences the speed of executing the function by the processing unit 102. The command system 130 minimizes the access time for command and state data by minimizing accesses to the internal cache memory 122.
The direct state data and command module 132 or “direct command module” is responsible for associating a payload repository buffer with a set of user defined CPU program instructions or delegates from the program 150, which operate on the state and command data stored within the payload repository buffer. This association may happen at run-time or compile time of the program 150. The payload stored in the payload repository buffer includes a payload header and a payload field that includes the actual payload. The payload may include commands and state data that are communicated and transferred between program functions of the program 150 and are selected depending on the requirements of the program function. This association between a payload and a CPU instruction based on a program function (delegate) is facilitated by the payload header, which is used to map the delegates to payloads associated with the direct command module 132 and used to reference the delegates.
The payload header provides context with which the direct command module 132 can operate on and transfer payloads. The deferred program operation (delegate) used in conjunction with the payload may be any typical reference to program code of the program 150 including, but not limited, to static/global program methods and object member functions. The direct command module 132 also accesses delegates to create a payload header map 210 that associates payloads with specific delegates.
The direct command module 132 is associated with the functions of binding delegates, unbinding delegates, and flushes. The bind delegate to payload identifier function takes a user function or delegate of the program 150 and associates it with a payload ID header for a particular delegate arriving at the command system 130. The bind delegate function is expressed as:
As shown above, the flush function causes the direct command module 132 to iterate through all the currently active stored payloads in the payload repository buffers 202, 204, and 206, and, using the associated headers, makes the payload data required by the appropriate delegate available from the repository buffers thereby bypassing the cache memory 122. The flush function increases efficiency of delegate execution by minimizing memory accesses for both indirect and direct cache memory.
The above described bind delegate function, BindDelegateToPayloadIdentifer( ) is responsible for associating a delegate referenced by the direct command module 132 with the payload ID header (uniquePayloadID field) of a payload having data needed to execute the delegate. The bind delegate function is shown in the flow diagram 300 in
The same payload may be bound to other delegates. For example, in
Multiple payloads may be associated with a single delegate. For example, another payload such as a second payload is associated with the first delegate 330. This association is reflected in the creation of the entry 326 by the bind delegate function (320) in
When payloads are stored within the direct payload repository 144 and associated with a delegate by the direct command module 132, their associated payload headers are used to find the correct delegate via the map 210 in
Additional state data, which may modify the behavior of the delegate or flush, may also be associated with each binding of a delegate and the payload header via a user data field such as the user data field 336. The data binding is optional and may be used during communication to augment the behavior of the flush function.
The indirect command module 134 is associated with functions including a register direct module to payload function, an unregister direct module to payload function, and a flush function. These functions are operated as follows. The register direct module to payload function may be called as follows:
The register direct module to payload function, (RegisterDirectModuleToPayloadIdentifier), is responsible for associating a delegate and a direct module with a unique payload ID. Multiple direct module and payload pairs may be associated with a single unique payload identifier. This allows a single payload to be communicated to multiple direct modules.
Additional program state data may also be stored with each binding of the delegates to a direct module using a direct module unique ID (DirectModuleuniquePayloadID). This can be used by the flush function to modify its behavior.
The unregister direct module to payload function, (UnRegisterDirectModuleToPayloadIdentifier), will remove an associated delegate and direct module with a unique payload ID.
The flush function is responsible for iterating through all the currently active stored payloads and using the associated payload header, communicating the translated payload header (specific to each direct command module) and payload data to the repositories associated with direct command modules. As explained above, the flush functions performed by the direct command modules communicate the payload data to the associated delegates for execution. Due to the associated data stored when the direct module and delegate were registered, this communication may be executed via streaming or direct memory access (DMA) commands (based on the model or type of CPU) since the header for the payload of the indirect command module may be translated into headers consumable by the direct command modules in a small fixed local cache such as the cache 122. The resulting payload header is then streamed to each repository of the associated direct command module. The payloads themselves do not need translation, and as such may be streamed directly. This streaming is facilitated as the flush function only keeps track of the source and destination memory locations so the local cache 122 is not compromised.
Streaming is useful as the execution of a direct module delegate is typically deferred until the flush function is called by a direct module. In this way polluting the cache of the current CPU with the program memory of the destination program in addition to the program memory responsible for storing the delegate instructions may be avoided. This also avoids any additional memory access (and corresponding cache pollution) by deferring the execution of the delegate, which, in almost every case, will need to access additional program memory.
The payload repository area 140 used by both the direct and indirect command modules 132 and 134 is interchangeable and may be configured in multiple ways for different payload repositories depending on the program context. The payload repository area 140 is responsible for maintaining a section of program memory for payload repositories where storage of payloads and the associated payload headers associated with delegates of the program 150 are stored. The payload repositories may be configured based on several operating parameters, such as the amount of buffering (single, double, triple, . . . etc.). It may also maintain thread safety via several possible methods. This functionality may be abstracted by any combination of functional overloads at program run time or compile time. Payloads stored within the repositories of the payload repository area 140 are associated with a logical identifier, which is only required to be unique to the payload repository. This logical identifier is used to map the attributes of the payload (such as size and layout), as well as to map methods and operations associated with the direct and indirect command modules 132 and 134.
The payload repositories, such as the direct payload repository 144, are associated with the following program functions. The direct payload repository 144 may perform a lock buffer swap, (LockBufferSwap(<ThreadID: Optional>)), an unlock buffer swap (UnLockBufferSwap(<ThreadID: Optional>)), a swap receiving stream (SwapReceivingStream(<ThreadID:Optional>)), and a get receiving stream (GetReceivingStream(<ThreadID:Optional>)) function.
The lock buffer swap and unlock buffer swap functions are optional and may be used to guard against acquiring a receiving stream or swapping a receiving stream. These functions may also optionally take an identifier for a thread (threadID) to be used for various synchronization methods. For example, the swap receiving stream function may optionally take a thread identifier for thread safety and may be used in the case of buffered repositories. The get receiving stream function may optionally take a thread identifier for thread safety and is used to acquire a region of program memory in the direct payload repository 144 for which the payload header and payload may be stored.
The payload and the payload header are used in conjunction with each other to allow for storage, retrieval, iteration, and operation on the program state data and commands stored in the payload field. Payloads may be predefined by users or runtime defined as long as the payload header can associate sufficient data to allow the payload to be properly interpreted by the direct and indirect command modules 132 and 134. Payload headers are generated and associated dynamically with one or more payloads. While payloads and their associated headers may be written directly to the associated payload repository, additional methods may be defined that optimize their transfer to the repository. By utilizing streaming CPU instructions or DMA it is possible to build a local copy of the payload header along with the payload itself in a reusable section of program memory that is only cached by the current thread. Once the copy is fully populated it may be streamed to the destination memory of a payload repository for later communication to either direct or indirect command modules 132 and 134.
The payload and payload headers are associated with a push function, which is expressed as Push (<repository>, <PayloadHeader>, <Payload>, <ThreadID:Optional>). Thus the push function stores a payload ID header and associated payload in a payload repository buffer. The following is an example push function given with a streaming instruction:
The push function is responsible for taking the payload and payload header and storing them in the program memory storage associated with a payload repository such as the direct payload repository 144 in
The program flow for an example direct module such as the direct command module 132 may be performed as follows. First a direct module is defined as DirectModule DirectModuleInstance(<repository>). Then the bind delegate command (BindDelegateToPayloadIdentifler( )) is used to associate a delegate with a unique payloadID for the direct module. Each delegate is bound to a payload identifier as follows:
BindDelegateToPayloadIdentifier(DirectModuleInstance, payloadID0, OnPayloadID0( ));
BindDelegateToPayloadIdentifier(DirectModuleInstance, payloadID1,
UserInstance::OnPayloadID1( ));
BindDelegateToPayloadIdentifier(DirectModuleInstance, payloadID2, OnPayloadID2( ));
The number of bindings allowed and the binding itself need not be static, and may be changed during execution if needed. During execution, payloads may be stored with the direct payload repository 144 of the direct command module 132 using the push function. This is shown as follows:
Push(DirectModuleInstance, Payload0, PayloadHeader0);
Push(DirectModuleInstance, Payload1, PayloadHeader1);
Push(DirectModuleInstance, Payload2, PayloadHeader2);
The payloads are then propagated to the delegates during the flush function. The flush function of the direct command module is not required to order the payload propagation, however it may be chosen to by overloading the flush function. While the default would be serial execution of payloads A, B, C, in order, an overloaded Flush( )function could re-order the execution of payloads if needed. For example, if payload B has higher priority than payload A, the flush function would first propagate payload B, then payload A, then payload C. Or, in another case, payloads A, B, and C could all be propagated on separate threads such that payloads A, B, and C are all executed at the same time.
The program flow for an indirect module such as the indirect command module 134 is similar. First direct modules that will be bound to the indirect module are created. Direct modules may be created and added to the indirect module at any suitable time.
DirectModule DirectModule0<repository0>;
DirectModule DirectModulel<repositoryl>;
DirectModule DirectModule2<repository2>;
Then the indirect command module 134 is created by the function, IndirectModule IndirectModuleInstance <repository3>. The direct modules may be bound as follows in the below example. In this example, there are three direct modules registered for a first payload (PayloadID0). There is one direct module register for the first payload (PayloadID1):
RegisterDirectModuleToPayloadIdentifier(IndirectModuleInstance,
PayloadHeader0,
DirectModule0,
DirectModule0::OnPayload0( )
DirectModule0::UserData);
RegisterDirectModuleToPayloadIdentifier(IndirectModuleInstance,
PayloadHeader0,
DirectModule1,
DirectModule1::OnPayload0( ),
DirectModule1::UserData);
RegisterDirectModuleToPayloadIdentifier(IndirectModuleInstance,
PayloadHeader0,
DirectModule2,
DirectModule2::OnPayload0( ),
DirectModule2::UserData);
RegisterDirectModuleToPayloadIdentifier(IndirectModuleInstance,
PayloadHeader1,
DirectModule0,
DirectModule0::OnPayload1( ),
DirectModule0::UserData);
Then during execution, payloads can be stored with the indirect payload repository 142 of the indirect command module 134 using the push function:
Push(IndirectModuleInstance, Payload0, PayloadHeader0);
Push(IndirectModuleInstance, Payload1, PayloadHeader1);
Push(IndirectModuleInstance, Payload2, PayloadHeader2);
The flush function allows the payloads to be distributed to the direct modules that have been registered for them. In the previous case, the DirectModules (0, 1 and 2) will all be presented with the payload data of PayloadID0. The DirectModule0 will also be presented with the payload data of PayloadID1. Since there are no registered direct modules for PayloadID2, it will not be broadcast at all.
The advantage of the system 100 is to limit the reads by the processor unit 102 from the external memory 110 to the cache memory 122. Communication of needed program state data and commands to delegates is facilitated by minimizing the time of polling since only the requested payloads are flushed to registered modules and delegates, thereby eliminating the need for polling for information. Eliminating the need for polling to determine whether new data exists or not reduces the pressure on the processor cache 122 and external memory 110.
The translation of the payload header using the tables allows direct writing efficiently without rewriting payload data from external memory 110 for a delegate.
The push function takes the payloads and associated payload headers and streams them into a memory location thus avoiding the computationally expensive task of polling all of the external memory 110 for the required data. The access to the cache memory 122 is limited to the flush functions. Since the delegates are deferred in execution, the data used for each delegate is prevented from contending with other threads.
The process of scheduling worker threads for tasks may be controlled on the example system 100 will now be described with reference to
On executing a delegate, the flush function is run (808) that iterates through all of the payloads in the payload repository buffers and makes the payloads available to the delegates as they are executed. The flush function reads the payload ID of the first payload (810). The flush function uses the map 210 to determine the associated delegate for the payload (812). The delegates are then executed with the loaded payloads containing the commands and state data needed to execute the delegates (814). The flush function then determines whether the payload ID is the last payload in the payload repository buffer (816). If the payload repository includes more payloads, the flush function loops back and reads the next payload ID (810). If the payload repository does not include any more payloads, the flush function concludes.
Each of these embodiments and obvious variations thereof is contemplated as falling within the spirit and scope of the claimed invention, which is set forth in the following claims.
Number | Date | Country | |
---|---|---|---|
Parent | 15710484 | Sep 2017 | US |
Child | 16120856 | US | |
Parent | 15368214 | Dec 2016 | US |
Child | 15710484 | US | |
Parent | 15013758 | Feb 2016 | US |
Child | 15368214 | US | |
Parent | 14155833 | Jan 2014 | US |
Child | 15013758 | US |