Register resource allocation method, computer device, readable storage medium and program product
By constructing function groups and generating configuration instructions, the register conflict problem when coroutine functions call device functions was resolved, and the correct mapping and execution of coroutine functions and device functions were achieved.
Patent Information
- Application Number
- CN202511596525.0
- Authority / Receiving Office
- CN · China
- Patent Type
- Patents(China)
- Current Assignee / Owner
- Filing Date
- 2025-11-04
- Publication Date
- 2026-03-03
- Estimated Expiration
- 2045-11-04
AI Technical Summary
Existing technologies are prone to physical register conflicts when coroutine functions call device functions, leading to function execution errors and failing to meet the dynamic register resource requirements of coroutines.
By constructing function groups, based on the calling relationships of coroutine functions and the amount of register usage, the register constraints of device functions are determined, and configuration instructions are generated to realize the offset mapping from register logical addresses to physical registers, thus avoiding conflicts.
This effectively avoids register conflicts when different coroutine functions call the same device function, ensuring the correctness and efficiency of function execution.
Smart Images

Figure CN121070434B_ABST
Abstract
Description
Technical Field
[0001] This application relates to the field of artificial intelligence chip technology, and in particular to a register resource allocation method, computer device, computer-readable storage medium, and computer program product. Background Technology
[0002] In the fields of parallel and heterogeneous computing, the collaborative optimization of hardware architecture and programming models is the core direction for improving computing efficiency. Coroutine functions, by initiating coroutines, can efficiently realize collaborative work in patterns such as consumer-producer, adding a concurrent dimension to device programming in addition to SIMT (Single Instruction Multiple Threads) parallelism, significantly expanding the application scenarios of parallel computing.
[0003] To adapt to coroutine scenarios, related technologies have been extended to include a register allocation method based on function groups: a function group containing coroutine kernel functions and coroutine subfunctions is constructed through function call relationships, and registers are allocated uniformly based on the resource record table to ensure that there are no conflicts in the local code of the coroutines within the group and that the shared variable registers are consistent, thus meeting the basic operational requirements of coroutines.
[0004] However, this method does not support coroutine functions calling ordinary device functions (hereinafter referred to as device functions). As a non-kernel function, the code generation and register allocation of device functions are independent of the calling coroutine, and resources need to be allocated from the global register pool. As a result, when multiple coroutines call the same device function, physical register conflicts are very likely to occur, leading to function execution errors. Summary of the Invention
[0005] Therefore, it is necessary to provide a register resource allocation method, computer device, computer-readable storage medium, and computer program product that can solve the register conflict problem when multiple coroutines call the same device function, in order to address the above-mentioned technical problems.
[0006] In a first aspect, this application provides a register resource allocation method, the method comprising:
[0007] Function groups are constructed by the calling relationships between functions, register resources are allocated to each coroutine function in the function group, and corresponding assembly instructions are generated.
[0008] Based on the register usage of each coroutine function, the register constraints of each device function are determined. Based on the register constraints, register resources are allocated to each device function and corresponding assembly instructions are generated. The register constraints are the upper limit of the registers used by the device function.
[0009] After all functions have completed register resource allocation, a configuration config instruction is generated for each of the aforementioned coroutine functions based on the allocation results. Assembly code for implementing register resource allocation is generated based on each of the aforementioned assembly instructions and the config instruction of each of the aforementioned coroutine functions.
[0010] The assembly instructions are used to indicate the allocated register logical address, and the config instructions are used to implement the offset mapping from the register logical address to the physical register.
[0011] In one embodiment, determining the register constraints of each device function based on the register usage of each of the coroutine functions includes:
[0012] For any of the aforementioned device functions, determine the target coroutine functions that call the device function;
[0013] The register usage of each target coroutine function is calculated, and the minimum value among the register usages is used as the register constraint of the device function.
[0014] In one embodiment, allocating register resources to each of the device functions based on the register constraints includes:
[0015] For any of the device functions, a reservation operation is performed on the register resources in the resource pool based on the register constraints of the device function, and register resources are allocated to the device function based on the register resources in the resource pool after the reservation operation.
[0016] In one embodiment, generating configuration directives for each of the coroutine functions based on the allocation result includes:
[0017] Traverse the compiled files to determine the call index of each of the coroutine subfunctions, the call index being used to characterize the call order of the coroutine subfunctions;
[0018] For any coroutine subfunction, based on the call index of the coroutine subfunction and the register usage of each coroutine function in the allocation result, the config instruction parameter value of the coroutine subfunction is determined, and the config instruction parameter value is used to characterize the offset;
[0019] The config directive for the coroutine subfunction is generated based on the config directive parameter value.
[0020] In one embodiment, register resources for shared variables are allocated in ascending order. The step of determining the `config` instruction parameter value of the coroutine subfunction based on its call index and the register usage of each coroutine function in the allocation result includes:
[0021] The register usage of each target coroutine subfunction is accumulated to obtain the initial parameter value, wherein the call index of the target coroutine subfunction is less than the call index of the coroutine subfunction;
[0022] The sum of the initial parameter value and the register usage of the coroutine kernel function is used as the config instruction parameter value of the coroutine subfunction.
[0023] In one embodiment, the step of generating assembly code for implementing register resource allocation based on the assembly instructions and the config instructions of the coroutine functions includes:
[0024] Insert the config instruction of the coroutine subfunction at the beginning of the assembly instruction corresponding to the coroutine subfunction, insert a preset config instruction before the read and write instructions for shared variables, and insert the config instruction of the coroutine subfunction after the read and write instructions for shared variables to obtain assembly code for implementing register resource allocation, wherein the config instruction parameter value of the preset config instruction is 0.
[0025] In one embodiment, register resources for shared variables are allocated in descending order. The step of determining the `config` instruction parameter value of the coroutine subfunction based on its call index and the register usage of each coroutine function in the allocation result includes:
[0026] The register usage of each target coroutine subfunction is accumulated to obtain the config instruction parameter value of the coroutine subfunction, where the call index of the target coroutine subfunction is less than the call index of the coroutine subfunction.
[0027] In one embodiment, the step of generating assembly code for implementing register resource allocation based on the assembly instructions and the config instructions of the coroutine functions includes:
[0028] Insert the config instruction of the coroutine subfunction at the beginning of the assembly instruction corresponding to the coroutine subfunction, and adjust the read and write instructions for shared variables according to the config instruction parameter value to obtain the assembly code used to implement register resource allocation.
[0029] In one embodiment, the coroutine functions in the function group include a coroutine kernel function and at least one coroutine subfunction, and the allocation of registers for each coroutine function in the function group includes:
[0030] The coroutine functions in the function group are moved to the beginning of the compiled file, and the coroutine kernel function is placed before each of the coroutine sub-functions;
[0031] The compiled file is traversed, and register resources are allocated for each coroutine function traversed.
[0032] Secondly, this application also provides a register resource allocation apparatus, the apparatus comprising:
[0033] The first allocation module is used to construct a function group based on the calling relationship between functions, allocate register resources to each coroutine function in the function group and generate corresponding assembly instructions;
[0034] The second allocation module is used to determine the register constraints of each device function based on the register usage of each coroutine function, allocate register resources to each device function based on the register constraints and generate corresponding assembly instructions, wherein the register constraints are the upper limit of the registers used by the device function;
[0035] The generation module is used to generate configuration instructions for each of the coroutine functions based on the allocation results after all functions have completed register resource allocation, and to generate assembly code for implementing register resource allocation based on the assembly instructions and the configuration instructions of each of the coroutine functions.
[0036] The assembly instructions are used to indicate the allocated register logical address, and the config instructions are used to implement the offset mapping from the register logical address to the physical register.
[0037] In one embodiment, determining the register constraints of each device function based on the register usage of each of the coroutine functions includes:
[0038] For any of the aforementioned device functions, determine the target coroutine functions that call the device function;
[0039] The register usage of each target coroutine function is calculated, and the minimum value among the register usages is used as the register constraint of the device function.
[0040] In one embodiment, allocating register resources to each of the device functions based on the register constraints includes:
[0041] For any of the device functions, a reservation operation is performed on the register resources in the resource pool based on the register constraints of the device function, and register resources are allocated to the device function based on the register resources in the resource pool after the reservation operation.
[0042] In one embodiment, generating configuration directives for each of the coroutine functions based on the allocation result includes:
[0043] Traverse the compiled files to determine the call index of each of the coroutine subfunctions, the call index being used to characterize the call order of the coroutine subfunctions;
[0044] For any coroutine subfunction, based on the call index of the coroutine subfunction and the register usage of each coroutine function in the allocation result, the config instruction parameter value of the coroutine subfunction is determined, and the config instruction parameter value is used to characterize the offset;
[0045] The config directive for the coroutine subfunction is generated based on the config directive parameter value.
[0046] In one embodiment, register resources for shared variables are allocated in ascending order. The step of determining the `config` instruction parameter value of the coroutine subfunction based on its call index and the register usage of each coroutine function in the allocation result includes:
[0047] The register usage of each target coroutine subfunction is accumulated to obtain the initial parameter value, wherein the call index of the target coroutine subfunction is less than the call index of the coroutine subfunction;
[0048] The sum of the initial parameter value and the register usage of the coroutine kernel function is used as the config instruction parameter value of the coroutine subfunction.
[0049] In one embodiment, the step of generating assembly code for implementing register resource allocation based on the assembly instructions and the config instructions of the coroutine functions includes:
[0050] Insert the config instruction of the coroutine subfunction at the beginning of the assembly instruction corresponding to the coroutine subfunction, insert a preset config instruction before the read and write instructions for shared variables, and insert the config instruction of the coroutine subfunction after the read and write instructions for shared variables to obtain assembly code for implementing register resource allocation, wherein the config instruction parameter value of the preset config instruction is 0.
[0051] In one embodiment, register resources for shared variables are allocated in descending order. The step of determining the `config` instruction parameter value of the coroutine subfunction based on its call index and the register usage of each coroutine function in the allocation result includes:
[0052] The register usage of each target coroutine subfunction is accumulated to obtain the config instruction parameter value of the coroutine subfunction, where the call index of the target coroutine subfunction is less than the call index of the coroutine subfunction.
[0053] In one embodiment, the step of generating assembly code for implementing register resource allocation based on the assembly instructions and the config instructions of the coroutine functions includes:
[0054] Insert the config instruction of the coroutine subfunction at the beginning of the assembly instruction corresponding to the coroutine subfunction, and adjust the read and write instructions for shared variables according to the config instruction parameter value to obtain the assembly code used to implement register resource allocation.
[0055] In one embodiment, the coroutine functions in the function group include a coroutine kernel function and at least one coroutine subfunction, and the allocation of registers for each coroutine function in the function group includes:
[0056] The coroutine functions in the function group are moved to the beginning of the compiled file, and the coroutine kernel function is placed before each of the coroutine sub-functions;
[0057] The compiled file is traversed, and register resources are allocated for each coroutine function traversed.
[0058] Thirdly, this application also provides a computer device, including a memory and a processor, wherein the memory stores a computer program, and the processor executes the computer program to implement any of the above-mentioned register resource allocation methods.
[0059] Fourthly, this application also provides a computer-readable storage medium having a computer program stored thereon, wherein the computer program, when executed by a processor, implements any of the above-mentioned register resource allocation methods.
[0060] Fifthly, this application also provides a computer program product, including a computer program that, when executed by a processor, implements any of the above-mentioned register resource allocation methods.
[0061] The aforementioned register resource allocation method, computer device, computer-readable storage medium, and computer program product construct function groups through function call relationships, allocate registers for each coroutine function within the function group, and generate corresponding assembly instructions. Based on the register usage of each coroutine function, register constraints for each device function are determined. Register resources are then allocated to each device function based on these constraints, and corresponding assembly instructions are generated. The register constraint is the upper limit of registers used by the device function. Further, after all functions have completed register resource allocation, a configuration instruction (config) is generated for each coroutine function based on the allocation results. Assembly code for implementing register resource allocation is generated based on each assembly instruction and the configuration instruction of each coroutine function. The register addresses indicated in the assembly instructions are logical addresses, and the configuration instructions are used to implement the offset mapping from the logical register address to the physical register. The register resource allocation method, computer device, computer-readable storage medium, and computer program product provided in this application restrict the register usage range of the device function through register constraints to ensure that its logical address does not exceed the register usage range of all callers (coroutine functions that call the device function). Furthermore, the config instruction is used to implement offset mapping of register logical addresses to map the logical addresses of coroutine functions and device functions to different physical registers, thereby avoiding register conflicts when different coroutine functions call the same device function. Attached Figure Description
[0062] To more clearly illustrate the technical solutions in the embodiments of this application or related technologies, the drawings used in the description of the embodiments of this application or related technologies will be briefly introduced below. Obviously, the drawings described below are only some embodiments of this application. For those skilled in the art, other related drawings can be obtained based on these drawings without creative effort.
[0063] Figure 1 This is a schematic diagram of parallel computation along the coroutine dimension in one embodiment;
[0064] Figure 2 This is a schematic diagram of a function call chain in one embodiment;
[0065] Figure 3 This is a flowchart illustrating a register resource allocation method in one embodiment;
[0066] Figure 4 This is a flowchart illustrating step 304 in one embodiment;
[0067] Figure 5 This is a flowchart illustrating step 306 in one embodiment;
[0068] Figure 6 This is a flowchart illustrating step 504 in one embodiment;
[0069] Figure 7 This is a flowchart illustrating step 302 in one embodiment;
[0070] Figure 8 This is a schematic diagram of a function call chain in another embodiment;
[0071] Figure 9 This is a schematic diagram of a function call chain that allocates register resources for shared variables in descending order in one embodiment.
[0072] Figure 10 This is a structural block diagram of a register resource allocation device in one embodiment;
[0073] Figure 11 This is an internal structural diagram of a computer device in one embodiment. Detailed Implementation
[0074] To make the objectives, technical solutions, and advantages of this application clearer, the following detailed description is provided in conjunction with the accompanying drawings and embodiments. It should be understood that the specific embodiments described herein are merely illustrative and not intended to limit the scope of this application.
[0075] It should be noted that the terms "first," "second," etc., used in this application can be used to describe various elements, but these elements are not limited by these terms. These terms are only used to distinguish the first element from the second element. The terms "comprising" and "having," and any variations thereof, used in this application, are intended to cover non-exclusive inclusion. The term "multiple" used in this application refers to two or more. The term "and / or" used in this application refers to one of the embodiments, or any combination of multiple embodiments.
[0076] In the fields of parallel and heterogeneous computing, coroutine kernel function technology adds a new dimension of concurrency to device programming beyond SIMT parallelism by introducing an asynchronous execution model. With the support of specific hardware architectures, kernel function threads can start coroutines asynchronously and achieve synchronous control using coroutine semaphores. Typical application scenarios include the consumer-producer pattern. (See reference...) Figure 1 As shown, coroutines can execute alternately (for example, the first coroutine (also represented as coroutine #0) and the second coroutine (also represented as coroutine #1) can execute alternately), and threads within a coroutine can execute in parallel. Figure 1 Parallel threads are represented by parallel downward arrows.
[0077] However, in the context of coroutine programming for AI chips, existing function calling methods are limited by fixed function calling conventions, making it difficult to meet the register isolation requirements when coroutines call functions (which can also be represented as device functions). Taking a specific calling scenario as an example, refer to... Figure 2 As shown, coroutine kernel function A (which can also be represented as coroutine kernel A) calls coroutine function 0 (which can also be represented as coroutine 0) and coroutine function 1 (which can also be represented as coroutine 1), and coroutine function 0 and coroutine function 1 must both call the same device function 0 (device function 0 can be represented as device0, and the calling relationship is as follows). Figure 2 (As shown). In related technologies, the function calling protocol of device0 is fixed, that is, no matter which coroutine function calls it, its parameter registers (such as R0-R3) and return value registers are all preset fixed values.
[0078] However, the actual requirements for coroutine execution are clear: when coroutine function 0 calls device0, it must ensure that the registers actually used by device0 fall within the range of R12-R40; when coroutine function 1 calls device0, the registers actually used by device0 must fall within the range of R41-R63. This requirement that the same device function needs to use different physical register blocks depending on the coroutine it calls fundamentally conflicts with the fixed calling convention in related technologies. In other words, under the fixed protocol, the register usage range of device0 cannot dynamically adapt to the resource constraints of different coroutines, which can easily lead to register conflicts when different coroutines call device0, thereby causing code execution errors.
[0079] This application provides a register resource allocation method. By setting register constraints for device functions to limit the register usage scope of device functions, and combining configuration instructions (which can also be represented as config instructions) to achieve offset mapping of register logical addresses to physical registers, the logical addresses of coroutine functions and device functions are mapped to different physical registers, thereby avoiding register conflicts when different coroutine functions call the same device function.
[0080] In one exemplary embodiment, such as Figure 3 As shown, a register resource allocation method is provided. This embodiment illustrates the method by applying it to a compiler deployed on the host side. It is understood that the host side may include a CPU (Central Processing Unit). In this embodiment, the method includes steps 302 to 306, wherein:
[0081] Step 302: Construct a function group through the calling relationship between functions, allocate register resources for each coroutine function in the function group and generate corresponding assembly instructions, wherein the assembly instructions are used to indicate the logical address of the allocated register.
[0082] In this embodiment, the direct and indirect call relationships between functions are first analyzed by traversing the compiled file, and a function group is constructed based on these call relationships. For example, a function group may include a coroutine kernel function and at least one coroutine subfunction, where the coroutine kernel function is the entry point function of the coroutine and is not called by other functions, and the coroutine subfunction is a coroutine function that is called directly or indirectly only by the coroutine kernel function. For instance, if coroutine kernel function A directly calls coroutine subfunction 0 and indirectly calls coroutine subfunction 1, then coroutine kernel function A, coroutine subfunction 0, and coroutine subfunction 1 can together construct a function group.
[0083] After the function group is constructed, the compiler can use register allocation logic based on the function group to allocate register resources for all coroutine functions (including coroutine kernel functions and coroutine subfunctions) within the group and generate corresponding assembly instructions.
[0084] Step 304: Based on the register usage of each coroutine function, determine the register constraints of each device function, allocate register resources to each device function based on the register constraints, and generate corresponding assembly instructions. The register constraints are the upper limit of the registers used by the device function.
[0085] In this embodiment of the application, after completing the register allocation for the coroutine functions, the compiler can traverse the compilation file again to count the register usage of each coroutine function, such as coroutine subfunction 0 using 40 registers and coroutine subfunction 1 using 38 registers, and determine the association between each device function and the coroutine function that calls it, such as device0 being called only by coroutine subfunction 0 and coroutine subfunction 1.
[0086] For any given device function, its register constraints are determined by the minimum number of registers used by all coroutine functions that call that device function. For example, taking device0 as an example, if coroutine subfunction 0 that calls it uses 40 registers and coroutine subfunction 1 uses 38 registers, then the register constraint for device0 is 38, meaning that device0 can use a maximum of 38 registers.
[0087] After determining the register constraints of the device function, the compiler can allocate register resources for the device function based on these constraints. When allocating register resources, the compiler selects register logical addresses only from the range corresponding to the register constraints. For example, it allocates R0-R37 to device0 and generates corresponding assembly instructions. These assembly instructions contain the specific usage of registers within this range. By analyzing these assembly instructions, the register logical address range of the device function can be obtained. These assembly instructions, together with the assembly instructions of the coroutine function, constitute the preliminary register allocation record.
[0088] Step 306: After all functions have completed register resource allocation, generate a configuration config instruction for each coroutine function based on the allocation result. Generate assembly code for implementing register resource allocation based on each assembly instruction and the config instruction of each coroutine function. The config instruction is used to implement the offset mapping from the register logical address to the physical register.
[0089] In this embodiment, after both the coroutine function and the device function have completed register allocation, the compiler generates a dedicated `config` instruction for each coroutine function based on the register allocation results of all functions. The `config` instruction is an instruction that implements the offset mapping from register logical addresses to physical registers. For example, generating a `config` instruction with an offset of 12 for coroutine subfunction 0 maps its allocated register logical addresses R0-R39 to physical register addresses R12-R51; generating a `config` instruction with an offset of 41 for coroutine subfunction 1 maps its allocated register logical addresses R0-R37 to physical register addresses R41-R77, thus ensuring that physical register addresses do not conflict when different coroutines call the same device function.
[0090] The compiler can integrate the assembly instructions for coroutine functions, device functions, and the config instructions for each coroutine function to form the final, correctly executable assembly code without register conflicts. That is, this assembly code includes the allocation of register logical addresses for coroutine functions and device functions, as well as the offset mapping operations from register logical addresses to physical register addresses. It can be directly loaded into the GPU by the driver, enabling efficient use of register resources in coroutine mode.
[0091] The aforementioned register resource allocation method constructs a function group based on the call relationships between functions, allocates register resources to each coroutine function within the function group, and generates corresponding assembly instructions. Furthermore, based on the register usage of each coroutine function, it determines the register constraints for each device function, and allocates register resources to each device function based on these constraints, generating corresponding assembly instructions. The register constraint is the upper limit of registers used by the device function. Further, after all functions have completed register resource allocation, it generates a configuration instruction (config) for each coroutine function based on the allocation results. Finally, it generates assembly code to implement register resource allocation based on the assembly instructions and the configuration instructions of each coroutine function. The register addresses indicated in the assembly instructions are logical addresses, and the configuration instructions are used to implement the offset mapping from the logical register address to the physical register. The register resource allocation method provided in this application restricts the register usage range of the device function through register constraints to ensure that its logical address does not exceed the register usage range of all callers (coroutine functions that call the device function). In addition, the config instruction is used to implement offset mapping of register logical addresses to map the logical addresses of coroutine functions and device functions to different physical registers, thereby avoiding register conflicts when different coroutine functions call the same device function.
[0092] In one exemplary embodiment, reference is made to Figure 4 As shown, in step 304, determining the register constraints of each device function based on the register usage of each coroutine function may include the following steps 402 to 404, wherein:
[0093] Step 402: For any given device function, determine the target coroutine functions that call the device function;
[0094] Step 404: Calculate the register usage of each target coroutine function and use the minimum register usage as the register constraint of the device function.
[0095] In this embodiment, the compiler first traverses the compiled file and constructs a call relationship table based on the call relationships between each device function and coroutine function. It then calculates the register usage of all coroutine functions and constructs a register mapping table based on each coroutine function and its register usage. For any given device function, the compiler can query the target coroutine function that calls it from the call relationship table and the register usage of each target coroutine function from the register mapping table. The minimum register usage among all target coroutine functions is used as the register constraint for that device function. The register constraint is the upper limit of registers that a device function can use, ensuring that the device function's register usage does not exceed the register usage range of any coroutine function that calls it.
[0096] For example, if the compiled file contains the following call relationships: coroutine0 calls device0, coroutine1 calls device0, and coroutine2 calls device1, then for the device0 function, its corresponding target coroutine functions are coroutine0 and coroutine1; for the device1 function, its corresponding target coroutine function is only coroutine2. If the register usage of the target coroutine function coroutine0 is 40 and the register usage of coroutine1 is 38, then the minimum value of 38 is taken as the register constraint of device0, meaning that device0 can only use a maximum of 38 registers during execution; if the register usage of the target coroutine function coroutine2 of device1 is 35, then the register constraint of device1 is directly determined to be 35. In this way, it can be ensured that the device function is compatible with all the coroutine functions that call it in terms of register resources, avoiding conflicts caused by the device function using too many registers.
[0097] In an exemplary embodiment, step 304, allocating register resources to each device function based on register constraints, may include:
[0098] For any device function, the register resources in the resource pool are reserved based on the register constraints of the device function, and the register resources in the resource pool after the reservation operation are allocated to the device function.
[0099] In this embodiment, the reservation process refers to removing register resources that exceed the register constraints from the resource pool. For example, if the register constraint for device0 is 38, registers with logical addresses greater than or equal to R38 (including R38 and above) in the resource pool will be marked as unallocated to device0, leaving only R0-R37 as the available register range. After the reservation process is completed, the compiler will allocate the register resources actually required for the execution of the device function from the remaining available register resources in the resource pool (e.g., allocate R0-R20 for device0) and record the allocation result.
[0100] In this way, it can be ensured that the register allocation of the device function is strictly limited to the constraints, avoiding resource conflicts with the coroutine function that calls it due to excessive usage.
[0101] In one exemplary embodiment, reference is made to Figure 5 As shown, in step 306, generating a configuration directive for each coroutine function based on the allocation result may include the following steps 502 to 506, wherein:
[0102] Step 502: Traverse the compiled files to determine the call index of each coroutine subfunction. The call index is used to represent the calling order of the coroutine subfunctions.
[0103] Step 504: For any coroutine subfunction, based on the call index of the coroutine subfunction and the register usage of each coroutine function in the allocation result, determine the config instruction parameter value of the coroutine subfunction. The config instruction parameter value is used to characterize the offset.
[0104] Step 506: Generate the config directive for the coroutine subfunction based on the config directive parameter values.
[0105] In this embodiment, the compiler traverses the compiled file, analyzes the order in which the coroutine kernel function calls each coroutine subfunction, and assigns a unique call index to each coroutine subfunction. This call index is a numerical identifier representing the order in which coroutine subfunctions are called, such as 1, 2, etc., used to distinguish the positions of different coroutine subfunctions in the execution sequence. For example, if coroutine kernel function A calls three coroutine subfunctions in the order coroutine0, coroutine1, and coroutine2, then the call index of coroutine0 is 1, the call index of coroutine1 is 2, and the call index of coroutine2 is 3.
[0106] For any given coroutine subfunction, the compiler can determine the coroutine subfunctions that were called before it by combining its call index, and calculate the config instruction parameter value of its config instruction by combining the register usage of the coroutine subfunctions that were called before it. The config instruction parameter value represents the offset from the logical address to the physical address used to avoid register conflicts.
[0107] After determining the config instruction parameter value of the coroutine subfunction, the compiler will generate the corresponding config instruction, which instructs the AI chip to automatically add the config instruction parameter value (offset) to the logical register address when executing coroutine1 and the device function it calls, thereby mapping it to the corresponding physical register address.
[0108] In one exemplary embodiment, register resources for shared variables are allocated in ascending order, referring to... Figure 6 As shown, in step 504, the config instruction parameter value of the coroutine subfunction is determined based on the call index of the coroutine subfunction and the register usage of each coroutine function in the allocation result. This may include the following steps 602 to 604, wherein:
[0109] Step 602: Accumulate the register usage of each target coroutine subfunction to obtain the initial parameter value. The call index of the target coroutine subfunction is less than the call index of the coroutine subfunction.
[0110] Step 604: The sum of the initial parameter value and the register usage of the coroutine kernel function is used as the parameter value of the config instruction of the coroutine subfunction.
[0111] In this embodiment, register resources are allocated using a general register allocation method, starting from R0 and proceeding in ascending order. For any coroutine subfunction, the compiler identifies the coroutine subfunction with a call index lower than that of the coroutine subfunction as the target coroutine subfunction. For example, assuming coroutine2 has a call index of 3, coroutine0 and coroutine1, with call indices of 1 and 2 respectively, are its target coroutine subfunctions. The compiler then accumulates the register usage of these target coroutine subfunctions, and the sum is the initial parameter value. For instance, if coroutine0 has a register usage of 40 and coroutine1 has a register usage of 38, the initial parameter value is 78.
[0112] After obtaining the initial parameter values, the compiler adds them to the register usage of the coroutine kernel function. The result is the parameter value of the `config` instruction for the current coroutine subfunction. For example, if the register usage of coroutine kernel function A is 12, and the initial parameter value of coroutine0 is 0 (no target coroutine subfunction), then its `config` instruction parameter value is 0 + 12 = 12; the initial parameter value of coroutine1 is 40 (the register usage of coroutine0), then its parameter value is 40 + 12 = 52; the initial parameter value of coroutine2 is 78, then its parameter value is 78 + 12 = 90.
[0113] In the embodiment of this application, by superimposing the resource usage of the coroutine kernel function, the physical register block of the coroutine subfunction is shifted to the back as a whole, so that it is completely isolated from the register block of the coroutine kernel function. At the same time, combined with the initial parameter value, the physical register blocks of the coroutine function are finally arranged in order according to the calling order, which can avoid register conflicts of all coroutine-related functions.
[0114] In an exemplary embodiment, step 306, generating assembly code for implementing register resource allocation based on each assembly instruction and the config instruction of each coroutine function, may include:
[0115] Insert the config instruction of the coroutine subfunction at the beginning of the assembly instruction corresponding to the coroutine subfunction, insert the preset config instruction before the read and write instructions for shared variables, and insert the config instruction of the coroutine subfunction after the read and write instructions for shared variables to obtain the assembly code used to implement register resource allocation, wherein the config instruction parameter value of the preset config instruction is 0.
[0116] In this embodiment, the compiler integrates the config instruction of the coroutine subfunction with various assembly instructions according to specific rules. This includes inserting the config instruction of the coroutine subfunction into the header of the assembly instructions corresponding to the coroutine subfunction, and for read and write instructions involving shared variables, inserting a preset config instruction (offset of 0) before its execution and re-inserting the config instruction of the coroutine subfunction after its execution, thus forming complete assembly code.
[0117] For example, a config instruction can be inserted at the beginning of a coroutine subroutine to ensure that the offset corresponding to the config instruction is enabled from the start of execution, so that the register logical address used by its local code can be correctly mapped to its dedicated physical block. For example, inserting a config instruction with offset 12 at the beginning of coroutine0 can ensure that its logical register address R0 is mapped to physical register address R12.
[0118] A preset config instruction (offset of 0) can be inserted before reading and writing shared variables. This preset config instruction can temporarily disable the offset mapping corresponding to the config instruction of the coroutine subfunction, so that the read and write instructions of shared variables can directly access the starting area of the physical register (such as R0-Rx), ensuring that all coroutine functions use the same physical address for shared variables.
[0119] Insert the config instruction of the coroutine subfunction after reading and writing shared variables to restore the offset mapping of the coroutine subfunction, ensuring that subsequent local code continues to use the dedicated physical register block of the coroutine subfunction and avoids register conflicts with other coroutine functions.
[0120] For example, if the `config` instruction parameter of `coroutine0` is 12, and it contains a write instruction to a shared variable, the final assembly code snippet is as follows:
[0121] coroutine 0:
[0122] config 12;
[0123] …
[0124] config 0;
[0125] read R0-R11; / / Read shared variables
[0126] config 12;
[0127] …
[0128] call device0.
[0129] If the `config` instruction of `coroutine1` has a parameter of 41 and contains a write instruction to a shared variable, the final assembly code snippet is as follows:
[0130] coroutine 1:
[0131] config 41;
[0132] …
[0133] config 0;
[0134] read R0-R11; / / Read shared variables
[0135] config 41;
[0136] …
[0137] call device0.
[0138] By using the above-mentioned config instruction insertion rules, we can ensure the isolation of register physical blocks in the coroutine's local code and achieve unified physical address access to shared variables, ultimately generating assembly code that can be safely executed directly on the artificial intelligence chip.
[0139] In one exemplary embodiment, register resources for shared variables are allocated in descending order. Based on the call index of the coroutine subfunction and the register usage of each coroutine function in the allocation result, the config instruction parameter value of the coroutine subfunction is determined, including:
[0140] The register usage of each target coroutine subfunction is accumulated to obtain the config instruction parameter value of the coroutine subfunction. The call index of the target coroutine subfunction is less than the call index of the coroutine subfunction.
[0141] In this embodiment of the application, the register resources are allocated using a general register allocation method, and the register resources are allocated to the shared variables in descending order starting from the highest address of the register resource pool. That is, the shared variables will use high address registers.
[0142] For any given coroutine subfunction, the compiler identifies the coroutine subfunctions with call indices lower than the call index of the given coroutine subfunction as target coroutine subfunctions. For example, assuming coroutine2 has a call index of 3, then coroutine0 and coroutine1, with call indices of 1 and 2 respectively, are its target coroutine subfunctions. The compiler then sums the register usage of these target coroutine subfunctions, and the sum is the value of the `config` instruction parameter for that coroutine subfunction. For instance, if coroutine0 uses 40 registers and coroutine1 uses 38 registers, then the value of the `config` instruction parameter is 78.
[0143] In this embodiment, by accumulating the resource usage of the preceding coroutine subfunction, an independent physical register block is allocated for the current coroutine subfunction. Combined with the descending allocation rule of shared variables, the shared variables use high-address registers, which are naturally isolated from the low-address registers of the coroutine local code. Therefore, there is no need to additionally add the register usage of the coroutine kernel function.
[0144] For example, if the total capacity of the register resource pool is R0-R100, and shared variables are allocated in descending order starting from R100 (e.g., R100, R99...), the call index of coroutine0 is 1, there is no target coroutine subfunction, and the register usage is 40, then its config instruction parameter value is 0; the call index of coroutine1 is 2, the target coroutine subfunction is coroutine0 (register usage 40), then its config instruction parameter value is 40.
[0145] At this point, the physical address ranges mapped by the offsets of the logical addresses of each coroutine subfunction are as follows: coroutine0 is offset from logical register address R0-R39 to physical register address R0-R39, which does not overlap with the high address register region of shared variables; coroutine1 is offset from logical register address R0-R37 to physical register address R40-R77.
[0146] The register allocation method provided in this application can ensure the isolation of physical register blocks of local code in different coroutine subfunctions, and can also use the descending allocation characteristic to naturally separate shared variables from local code registers without the need to insert additional temporary offset closing instructions, thus simplifying the assembly code generation logic.
[0147] In an exemplary embodiment, step 306, generating assembly code for implementing register resource allocation based on each assembly instruction and the config instruction of each coroutine function, may include:
[0148] Insert the config instruction of the coroutine subfunction at the beginning of the assembly instruction corresponding to the coroutine subfunction, and adjust the read and write instructions for shared variables according to the config instruction parameter value to obtain the assembly code used to implement register resource allocation.
[0149] In this embodiment, the compiler can insert a `config` instruction for the coroutine subfunction at the header of the assembly instruction corresponding to the coroutine subfunction. For example, inserting a `config` instruction at the header of the coroutine subfunction ensures that the offset corresponding to the `config` instruction is enabled from the initial execution stage of the coroutine subfunction, and that the register logical addresses used by its local code are accurately mapped to the corresponding dedicated physical blocks. For instance, if the parameter value of the `config` instruction for coroutine1 is 40, then its logical register address R0 will be mapped to the physical register address R40, and so on, ensuring isolation of the physical register blocks from other coroutine subfunctions.
[0150] Because shared variables are allocated in descending order, starting from the high address of the register resource pool, they are naturally separated from the local code registers of coroutine subfunctions, eliminating the need to temporarily disable the offset mapping corresponding to the `config` instruction. The compiler can directly adjust the target address of shared variable read / write instructions based on the parameter value of the `config` instruction in the current coroutine subfunction. This ensures that after executing the offset mapping operation corresponding to the `config` instruction, the shared variable is mapped to the physical register address, resulting in correctly executable assembly code without register conflicts. For example, if the logical address of the shared variable is R244-R255, and the offset of coroutine0 is 0, then the target address of its read / write instructions is logical address R244-R255. If the offset of coroutine1 is 12, its shared variable read / write instructions will subtract 12 from the target address, updating the target address to R232-R243. Thus, after executing the `config` instruction, the target address will be offset to R244-R255, ensuring that accesses to the same shared variable by different coroutines are mapped to the same physical register address.
[0151] For example, if the `config` instruction parameter of `coroutine0` is 0, and it contains a write instruction to a shared variable, the final assembly code snippet is as follows:
[0152] coroutine 0:
[0153] config 0;
[0154] …
[0155] read R244-R255; / / Read shared variables
[0156] …
[0157] call device0.
[0158] If the `config` instruction of coroutine1 has a parameter of 12 and contains a write instruction to a shared variable, the final assembly code snippet is as follows:
[0159] coroutine 1:
[0160] config 12;
[0161] …
[0162] read R232-R243; / / Read shared variables
[0163] …
[0164] call device0.
[0165] By using the above method, we can ensure the physical isolation of register blocks in the coroutine's local code, and also simplify the access logic of shared variables by taking advantage of the natural isolation characteristics of descending allocation, ultimately generating efficient and conflict-free assembly code.
[0166] In one exemplary embodiment, the coroutine functions in the function group include a coroutine kernel function and at least one coroutine subfunction, as shown below. Figure 7 As shown, in step 302, allocating registers for each coroutine function in the function group may include the following steps 702 to 704, wherein:
[0167] Step 702: Move the coroutine functions in the function group to the beginning of the compiled file, and place the coroutine kernel function before each coroutine subfunction;
[0168] Step 704: Traverse the compiled files and allocate register resources for each coroutine function being traversed.
[0169] In this embodiment of the application, the compiler can first preprocess the function order in the compiled file, including moving all coroutine functions (including coroutine kernel functions and coroutine subfunctions) in the function group to the header area of the compiled file, and ensuring that the position of the coroutine kernel function is before all coroutine subfunctions.
[0170] For example, if the function order in the original compiled file is ordinary function A, coroutine subfunction 0, coroutine kernel function A, ordinary function B, and coroutine subfunction 1, then the adjusted order will be coroutine kernel function A, coroutine subfunction 0, coroutine subfunction 1, ordinary function A, and ordinary function B.
[0171] After the position adjustment is completed, the compiler will traverse the compiled files according to the adjusted order. When it encounters a coroutine function, it will allocate register resources for it based on the resource constraints of the function group. That is, in this embodiment, the traversal and allocation follow the principle of kernel functions first, then sub-functions, prioritizing the allocation of registers for the coroutine kernel function, and then allocating register resources sequentially according to the order of the coroutine sub-functions in the compiled file.
[0172] In this embodiment, by combining position preposition and sequential traversal allocation, it is possible to ensure that the compiler prioritizes the processing of register requirements of coroutine functions, and to ensure that the register blocks of coroutine functions within the same function group are continuous and do not overlap through a fixed order, thus laying the foundation for the subsequent generation of config instructions.
[0173] To enable those skilled in the art to better understand the embodiments of this application, the embodiments of this application are described below through specific examples.
[0174] This application proposes a global register allocation method based on the config instruction. The config instruction is a hardware-provided instruction that can configure the register base address of the current program. Its scope includes all instructions from this instruction to the next config instruction. Its function is illustrated below:
[0175] config 16;
[0176] mov.b32 R1, R0; / / Rx actually corresponds to the physical register R[16+x]
[0177] …
[0178] config 20;
[0179] mov.b32 R1, R0 / / Rx actually corresponds to the physical register R[20+x].
[0180] In this embodiment of the application, the register allocation method includes the following four main steps:
[0181] Step 1: Modify the function order in the compilation unit;
[0182] Ensure that the coroutine kernel function allocates registers before the coroutine subfunctions;
[0183] Ensure that register allocation is performed by coroutine functions before that of ordinary device functions;
[0184] Step 2: Pass register constraints to the device function called by the coroutine;
[0185] Step 3: Allocate registers according to the register constraints of the Reserve register;
[0186] Step 4: Insert the config command.
[0187] The modification of the function order in the compilation unit in step 1 above may include the following steps:
[0188] Step 1.1: Traverse the functions of the entire compiled file, collecting all coroutine sub-functions and coroutine kernel functions;
[0189] Step 1.2: Move the coroutine sub-function definition to the beginning of the compiled file;
[0190] Step 1.3: Move the coroutine kernel function definition to the beginning of the compilation file.
[0191] For example, the following is an example of the compiled file before adjustment:
[0192] / / Translation Unit
[0193] device1:
[0194] …
[0195] device2:
[0196] …
[0197] coroutine kernel1: ...
[0199] coroutine 1:
[0200] …
[0201] coroutine 2:
[0202] …
[0203] coroutine kernel2:
[0204] …
[0205] coroutine 3:
[0206] …
[0207] coroutine 4:
[0208] …
[0209] coroutine 5:
[0210] …
[0211] The following is an example of the compiled file after adjustment:
[0212] / / Translation Unit
[0213] coroutine kernel1: ...
[0215] coroutine kernel2:
[0216] …
[0217] coroutine 1:
[0218] …
[0219] coroutine 2:
[0220] …
[0221] coroutine 3:
[0222] …
[0223] coroutine 4:
[0224] …
[0225] coroutine 5:
[0226] …
[0227] device1:
[0228] …
[0229] device2:
[0230] …
[0231] In step 2 above, passing the register count constraint to the device function called by the coroutine function according to the mapping table can specifically include the following steps:
[0232] Step 2.1: The device function can be represented as Device, and the coroutine function that calls the device function can be represented as Caller. Then, a Device->Caller mapping relationship can be constructed, denoted as CallerMap (i.e., the call relationship table).
[0233] Step 2.2: Calculate the register usage of all coroutine functions (which can be represented as Coroutines) (which can be represented as RegLimit), record the mapping relationship between coroutine functions and register usage {Coroutine, RegLimit}, and denote it as RegLimitMap (i.e., register mapping table).
[0234] Step 2.3: Traverse all device functions in the compiled file, query their Callers, and obtain all their coroutine Callers;
[0235] Step 2.4: Iterate through each coroutine caller, query RegLimitMap, and obtain the RegLimit corresponding to the coroutine caller;
[0236] Step 2.5: Calculate the register constraints of the device function according to the following formula and mark them on the function;
[0237] RegLimit Of Device = min(RegLimit of All callers);
[0238] For example, the calling relationship between functions is referenced. Figure 8As shown in the diagram (where each edge represents a function call relationship and the arrow points to the called function), assuming that coroutine kernel1 represents coroutine kernel function A, device0 represents device function 0, device1 represents device function 1, device2 represents device function 2, device3 represents device function 3, coroutine0 represents coroutine function 0, coroutine1 represents coroutine function 1, and coroutine2 represents coroutine function 2, then an example of CallerMap is as follows:
[0239] {device0, {coroutine0}};
[0240] {device1, {coroutine0, coroutine1}};
[0241] {device2, {coroutine1, coroutine2}};
[0242] {device3, {coroutine2}}.
[0243] In step 3 above, register allocation is performed based on the Reserved register constraint. The register constraint refers to the RegLimit corresponding to each device function obtained in step 2. Reserve means that unusable physical registers are removed from the resource pool before register allocation. For example, assuming the GPU has general-purpose registers R0-R255, the initial allocation resource pool is R0-R255; assuming RegLimit is 64, before allocation, R64-R255 are all marked as Reserved, and the resource pool at allocation time becomes R0-R63, thus ensuring that functions do not use physical registers outside of RegLimit. The register allocation uses a general register allocation method.
[0244] Inserting the config directive in step 4 above can include the following steps:
[0245] Step 4.1: Traverse the function list in the compiled file, record the order of the coroutine functions, and construct a mapping relationship between the coroutine functions and their order in the function group, denoted as IndexMap. The first coroutine function traversed has an Index (i.e., call index) of 1, and so on.
[0246] Step 4.2: Query the IndexMap to obtain the index of the current coroutine function in the function group;
[0247] Step 4.3: Based on RegLimitMap in Step 2 and Index in Step 4.2, calculate the config instruction parameter value of the current coroutine function, where the config instruction parameter value = sum(RegLimit Of coroutine[1~Index-1]+RegUsedBySharedVariable), and RegUsedBySharedVariable refers to the register usage of the coroutine kernel function.
[0248] Reference Figure 2 As shown, assuming the compilation order is coroutine kernel function kernelA, coroutine0 (RegLimit=29), coroutine1 (RegLimit=22), then for coroutine0, its config directive parameter value is 12; for coroutine1, its config directive parameter value is 41.
[0249] Step 4.4: Insert a config instruction at the beginning of the coroutine subfunction. The offset in the config instruction is the config instruction parameter value calculated in step 4.3. Also, insert a config instruction with an offset of 0 before the instructions for reading and writing shared variables.
[0250] In one example, the register allocation method for shared variables can be adjusted, prioritizing R255. The `config` directives inserted before and after reading and writing shared variables can be omitted. In this example, when reading and writing shared variables, their register numbers need to be subtracted from the value of the `config` directive parameter of the current coroutine function. See the example below. Figure 9 As shown.
[0251] The register allocation method provided in this application, using the hardware-provided config instruction, enables function calls within coroutine functions, avoiding register conflicts that occur when coroutine functions call the same device function. The advantage of this application is that it does not require changing the function calling protocol of ordinary device functions, nor does it require generating a copy for each function call; the goal can be achieved simply by modifying the register base address on the caller side.
[0252] It should be understood that although the steps in the flowcharts of the embodiments described above are shown sequentially according to the arrows, these steps are not necessarily executed in the order indicated by the arrows. Unless explicitly stated herein, there is no strict order restriction on the execution of these steps, and they can be executed in other orders. Moreover, at least some steps in the flowcharts of the embodiments described above may include multiple steps or multiple stages. These steps or stages are not necessarily completed at the same time, but can be executed at different times. The execution order of these steps or stages is not necessarily sequential, but can be performed alternately or in turn with other steps or at least some of the steps or stages in other steps. It is understood that the steps in different embodiments can be freely combined as needed, and all non-contradictory solutions formed by such combinations are within the scope of protection of this application.
[0253] Based on the same inventive concept, this application also provides a register resource allocation apparatus for implementing the register resource allocation method described above. The solution provided by this apparatus is similar to the implementation described in the above method; therefore, the specific limitations in one or more register resource allocation apparatus embodiments provided below can be found in the limitations of the register resource allocation method described above, and will not be repeated here.
[0254] In one exemplary embodiment, such as Figure 10 As shown, a register resource allocation device 1000 is provided, including: a first allocation module 1002, a second allocation module 1004, and a generation module 1006, wherein:
[0255] The first allocation module 1002 is used to construct a function group through the calling relationship between functions, allocate register resources to each coroutine function in the function group and generate corresponding assembly instructions;
[0256] The second allocation module 1004 is used to determine the register constraints of each device function based on the register usage of each coroutine function, allocate register resources to each device function based on the register constraints and generate corresponding assembly instructions, wherein the register constraints are the upper limit of the registers used by the device function;
[0257] The generation module 1006 is used to generate configuration config instructions for each of the coroutine functions based on the allocation results after all functions have completed register resource allocation, and to generate assembly code for implementing register resource allocation based on each assembly instruction and the config instructions of each of the coroutine functions.
[0258] The assembly instructions are used to indicate the allocated register logical address, and the config instructions are used to implement the offset mapping from the register logical address to the physical register.
[0259] The register resource allocation device provided in this application restricts the register usage range of the device function through register constraints to ensure that its logical address does not exceed the register usage range of all callers (coroutine functions that call the device function). In addition, the config instruction is used to implement offset mapping of register logical addresses to map the logical addresses of coroutine functions and device functions to different physical registers, thereby avoiding register conflicts when different coroutine functions call the same device function.
[0260] In one embodiment, determining the register constraints of each device function based on the register usage of each of the coroutine functions includes:
[0261] For any of the aforementioned device functions, determine the target coroutine functions that call the device function;
[0262] The register usage of each target coroutine function is calculated, and the minimum value among the register usages is used as the register constraint of the device function.
[0263] In one embodiment, allocating register resources to each of the device functions based on the register constraints includes:
[0264] For any of the device functions, a reservation operation is performed on the register resources in the resource pool based on the register constraints of the device function, and register resources are allocated to the device function based on the register resources in the resource pool after the reservation operation.
[0265] In one embodiment, generating configuration directives for each of the coroutine functions based on the allocation result includes:
[0266] Traverse the compiled files to determine the call index of each of the coroutine subfunctions, the call index being used to characterize the call order of the coroutine subfunctions;
[0267] For any coroutine subfunction, based on the call index of the coroutine subfunction and the register usage of each coroutine function in the allocation result, the config instruction parameter value of the coroutine subfunction is determined, and the config instruction parameter value is used to characterize the offset;
[0268] The config directive for the coroutine subfunction is generated based on the config directive parameter value.
[0269] In one embodiment, register resources for shared variables are allocated in ascending order. The step of determining the `config` instruction parameter value of the coroutine subfunction based on its call index and the register usage of each coroutine function in the allocation result includes:
[0270] The register usage of each target coroutine subfunction is accumulated to obtain the initial parameter value, wherein the call index of the target coroutine subfunction is less than the call index of the coroutine subfunction;
[0271] The sum of the initial parameter value and the register usage of the coroutine kernel function is used as the config instruction parameter value of the coroutine subfunction.
[0272] In one embodiment, the step of generating assembly code for implementing register resource allocation based on the assembly instructions and the config instructions of the coroutine functions includes:
[0273] Insert the config instruction of the coroutine subfunction at the beginning of the assembly instruction corresponding to the coroutine subfunction, insert a preset config instruction before the read and write instructions for shared variables, and insert the config instruction of the coroutine subfunction after the read and write instructions for shared variables to obtain assembly code for implementing register resource allocation, wherein the config instruction parameter value of the preset config instruction is 0.
[0274] In one embodiment, register resources for shared variables are allocated in descending order. The step of determining the `config` instruction parameter value of the coroutine subfunction based on its call index and the register usage of each coroutine function in the allocation result includes:
[0275] The register usage of each target coroutine subfunction is accumulated to obtain the config instruction parameter value of the coroutine subfunction, where the call index of the target coroutine subfunction is less than the call index of the coroutine subfunction.
[0276] In one embodiment, the step of generating assembly code for implementing register resource allocation based on the assembly instructions and the config instructions of the coroutine functions includes:
[0277] Insert the config instruction of the coroutine subfunction at the beginning of the assembly instruction corresponding to the coroutine subfunction, and adjust the read and write instructions for shared variables according to the config instruction parameter value to obtain the assembly code used to implement register resource allocation.
[0278] In one embodiment, the coroutine functions in the function group include a coroutine kernel function and at least one coroutine subfunction, and the allocation of registers for each coroutine function in the function group includes:
[0279] The coroutine functions in the function group are moved to the beginning of the compiled file, and the coroutine kernel function is placed before each of the coroutine sub-functions;
[0280] The compiled file is traversed, and register resources are allocated for each coroutine function traversed.
[0281] Each module in the aforementioned register resource allocation device can be implemented entirely or partially through software, hardware, or a combination thereof. These modules can be embedded in or independent of the processor in a computer device, or stored in the memory of a computer device in software form, so that the processor can call and execute the operations corresponding to each module.
[0282] In one exemplary embodiment, a computer device is provided, which may be a terminal, and its internal structure diagram may be as follows: Figure 11 As shown, the computer device includes a processor, memory, input / output interfaces, a communication interface, a display unit, and an input device. The processor, memory, and input / output interfaces are connected via a system bus, and the communication interface, display unit, and input device are also connected to the system bus via the input / output interfaces. The processor provides computing and control capabilities. The memory includes non-volatile storage media and internal memory. The non-volatile storage media stores the operating system and computer programs. The internal memory provides an environment for the operation of the operating system and computer programs stored in the non-volatile storage media. The input / output interfaces are used for exchanging information between the processor and external devices. The communication interface is used for wired or wireless communication with external terminals; wireless communication can be achieved through Wi-Fi, mobile cellular networks, Near Field Communication (NFC), or other technologies. When the computer program is executed by the processor, it implements a register resource allocation method. The display unit is used to form a visually visible image and can be a display screen, a projection device, or a virtual reality imaging device. The display screen can be an LCD screen or an e-ink screen. The input device of the computer device can be a touch layer covering the display screen, or buttons, trackballs, or touchpads set on the casing of the computer device, or external keyboards, touchpads, or mice, etc.
[0283] Those skilled in the art will understand that Figure 11The structure shown is merely a block diagram of a portion of the structure related to the present application and does not constitute a limitation on the computer device to which the present application is applied. Specific computer devices may include more or fewer components than those shown in the figure, or combine certain components, or have different component arrangements.
[0284] In one embodiment, a computer device is also provided, including a memory and a processor, wherein the memory stores a computer program, and the processor executes the computer program to implement the steps in the above method embodiments.
[0285] In one embodiment, a computer-readable storage medium is provided having a computer program stored thereon that, when executed by a processor, implements the steps in the above method embodiments.
[0286] In one embodiment, a computer program product is provided, including a computer program that, when executed by a processor, implements the steps in the above method embodiments.
[0287] It should be noted that the user information (including but not limited to user device information, user personal information, etc.) and data (including but not limited to data used for analysis, data stored, data displayed, etc.) involved in this application are all information and data authorized by the user or fully authorized by all parties, and the collection, use and processing of the relevant data must comply with relevant regulations.
[0288] Those skilled in the art will understand that all or part of the processes in the methods of the above embodiments can be implemented by a computer program instructing related hardware. The computer program can be stored in a non-volatile computer-readable storage medium, and when executed, it can include the processes of the embodiments of the above methods. Any references to memory, databases, or other media used in the embodiments provided in this application can include at least one of non-volatile memory and volatile memory. Non-volatile memory can include read-only memory (ROM), magnetic tape, floppy disk, flash memory, optical memory, high-density embedded non-volatile memory, resistive random access memory (ReRAM), magnetic random access memory (MRAM), ferroelectric random access memory (FRAM), phase change memory (PCM), graphene memory, etc. Volatile memory can include random access memory (RAM) or external cache memory, etc. By way of illustration and not limitation, RAM can take many forms, such as Static Random Access Memory (SRAM) or Dynamic Random Access Memory (DRAM). The databases involved in the embodiments provided in this application may include at least one type of relational database and non-relational database. Non-relational databases may include, but are not limited to, blockchain-based distributed databases. The processors involved in the embodiments provided in this application may be general-purpose processors, central processing units, graphics processing units, digital signal processors, programmable logic devices, quantum computing-based data processing logic devices, artificial intelligence (AI) processors, etc., and are not limited to these.
[0289] The technical features of the above embodiments can be combined in any way. For the sake of brevity, not all possible combinations of the technical features in the above embodiments are described. However, as long as there is no contradiction in the combination of these technical features, they should be considered to be within the scope of this application.
[0290] The embodiments described above are merely illustrative of several implementation methods of this application, and while the descriptions are specific and detailed, they should not be construed as limiting the scope of this patent application. It should be noted that those skilled in the art can make various modifications and improvements without departing from the concept of this application, and these all fall within the protection scope of this application. Therefore, the protection scope of this application should be determined by the appended claims.
Claims
1. A register resource allocation method, characterized in that, The method includes: Function groups are constructed by the calling relationships between functions, register resources are allocated to each coroutine function in the function group, and corresponding assembly instructions are generated. Based on the register usage of each coroutine function, the register constraints of each device function are determined. Based on the register constraints, register resources are allocated to each device function and corresponding assembly instructions are generated. The register constraints are the upper limit of the registers used by the device function. After all functions have completed register resource allocation, a configuration config instruction is generated for each of the aforementioned coroutine functions based on the allocation results. Assembly code for implementing register resource allocation is generated based on each of the aforementioned assembly instructions and the config instruction of each of the aforementioned coroutine functions. The assembly instructions are used to indicate the allocated register logical address, and the config instructions are used to implement the offset mapping from the register logical address to the physical register.
2. The method according to claim 1, characterized in that, The determination of register constraints for each device function based on the register usage of each coroutine function includes: For any of the aforementioned device functions, determine the target coroutine functions that call the device function; The register usage of each target coroutine function is calculated, and the minimum value among the register usages is used as the register constraint of the device function.
3. The method according to claim 1 or 2, characterized in that, The allocation of register resources to each of the device functions based on the register constraints includes: For any of the device functions, a reservation operation is performed on the register resources in the resource pool based on the register constraints of the device function, and register resources are allocated to the device function based on the register resources in the resource pool after the reservation operation.
4. The method according to claim 1 or 2, characterized in that, The step of generating configuration directives for each coroutine function based on the allocation result includes: Traverse the compiled files to determine the call index of each coroutine subfunction, whereby the call index is used to characterize the call order of the coroutine subfunctions; For any coroutine subfunction, based on the call index of the coroutine subfunction and the register usage of each coroutine function in the allocation result, the config instruction parameter value of the coroutine subfunction is determined, and the config instruction parameter value is used to characterize the offset; The config directive for the coroutine subfunction is generated based on the config directive parameter value.
5. The method according to claim 4, characterized in that, The register resources for shared variables are allocated in ascending order. The determination of the `config` instruction parameter value for each coroutine subfunction, based on its call index and the register usage of each coroutine function in the allocation result, includes: The register usage of each target coroutine subfunction is accumulated to obtain the initial parameter value, wherein the call index of the target coroutine subfunction is less than the call index of the coroutine subfunction; The sum of the initial parameter value and the register usage of the coroutine kernel function is used as the config instruction parameter value of the coroutine subfunction.
6. The method according to claim 5, characterized in that, The generation of assembly code for register resource allocation based on the assembly instructions and the config instructions of the coroutine functions includes: Insert the config instruction of the coroutine subfunction at the beginning of the assembly instruction corresponding to the coroutine subfunction, insert a preset config instruction before the read and write instructions for shared variables, and insert the config instruction of the coroutine subfunction after the read and write instructions for shared variables to obtain assembly code for implementing register resource allocation, wherein the config instruction parameter value of the preset config instruction is 0.
7. The method according to claim 5, characterized in that, The register resources for shared variables are allocated in descending order. The determination of the `config` instruction parameter value for each coroutine subfunction based on its call index and the register usage of each coroutine function in the allocation result includes: The register usage of each target coroutine subfunction is accumulated to obtain the config instruction parameter value of the coroutine subfunction, where the call index of the target coroutine subfunction is less than the call index of the coroutine subfunction.
8. The method according to claim 7, characterized in that, The generation of assembly code for register resource allocation based on the assembly instructions and the config instructions of the coroutine functions includes: Insert the config instruction of the coroutine subfunction at the beginning of the assembly instruction corresponding to the coroutine subfunction, and adjust the read and write instructions for shared variables according to the config instruction parameter value to obtain the assembly code used to implement register resource allocation.
9. The method according to claim 1, characterized in that, The coroutine functions in the function group include a coroutine kernel function and at least one coroutine subfunction. Allocating registers for each coroutine function in the function group includes: The coroutine functions in the function group are moved to the beginning of the compiled file, and the coroutine kernel function is placed before each of the coroutine sub-functions; The compiled file is traversed, and register resources are allocated for each coroutine function traversed.
10. A computer device comprising a memory and a processor, wherein the memory stores a computer program, characterized in that, When the processor executes the computer program, it implements the steps of the method according to any one of claims 1 to 9.
11. A computer-readable storage medium having a computer program stored thereon, characterized in that, When the computer program is executed by a processor, it implements the steps of the method according to any one of claims 1 to 9.
12. A computer program product, comprising a computer program, characterized in that, When the computer program is executed by a processor, it implements the steps of the method according to any one of claims 1 to 9.
Citation Information
Patent Citations
Program code compiling method and device, electronic equipment and storage medium
CN114661296A
General register dynamic allocation method and device, computer equipment and storage medium
CN115934102A