Program compiling method and device, electronic equipment, storage medium and program product
By identifying task interfaces and generating executable code for coprocessors and central processing units during program compilation, the automatic conversion from a unified program to compilation results is achieved, solving the problem of developers writing multiple sets of code for heterogeneous platforms and improving compilation efficiency.
Patent Information
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2026-03-09
- Publication Date
- 2026-04-07
AI Technical Summary
In existing technologies, developers need to write and maintain two separate sets of code for the central processing unit and the coprocessor, which leads to high development complexity, large workload, limited program portability, easy introduction of concurrent errors, and low compilation efficiency.
By obtaining the task interface in the program to be processed, the first executable code of the coprocessor task is generated, and the original logic is updated to the control logic of the central processing unit to generate the second executable code of the central processing unit task, thereby realizing the automated encapsulation of the compilation result.
It reduces the workload of manually writing low-level interaction logic, avoids independent code maintenance and concurrency errors, and improves compilation efficiency.
Smart Images

Figure CN121807276A_ABST
Abstract
Description
Technical Field
[0001] This application relates to the field of computer technology, and in particular to a method for compiling a program, an apparatus, an electronic device, a storage medium, and a program product. Background Technology
[0002] To improve computing performance and energy efficiency, related technologies typically integrate a general-purpose central processing unit (CPU) with one or more dedicated coprocessors. The CPU is responsible for handling general control flow and logic tasks, while the coprocessors focus on performing specific computationally intensive tasks, such as graphics rendering or data-parallel computing. This architecture requires the program to be processed to contain CPU tasks executed by the CPU and coprocessor tasks executed by the coprocessors. However, the program compilation process for such heterogeneous platforms faces challenges.
[0003] In related technologies, developers are typically required to write and maintain two separate sets of code for the central processing unit (CPU) and coprocessor. Developers need to use different software development toolchains to compile and generate executable code for the CPU and coprocessor respectively. Developers must also manually write the low-level code for interaction between the two, including complex control logic such as data transfer, task initiation, and execution synchronization. This approach not only increases the complexity and workload of development, but also tightly couples the code to a specific hardware platform. When the hardware platform changes, a lot of code modifications are required, which limits the portability of the program. Furthermore, manually managing the interaction between processors can easily introduce difficult-to-debug concurrent errors, resulting in low compilation efficiency. Summary of the Invention
[0004] This application provides a method, apparatus, electronic device, computer-readable storage medium, and computer program product for compiling a program, which can effectively improve compilation efficiency.
[0005] The technical solution of this application embodiment is implemented as follows: This application provides a method for compiling a program, including: Obtain a program to be processed, which includes a central processing unit task executed by the central processing unit and a coprocessor task executed by the coprocessor. From the program to be processed, determine the task interface used to instruct the coprocessor task to be assigned to the coprocessor for execution; Based on the logical relationship of the task interface in the program to be processed, the first executable code of the coprocessor task on the coprocessor is generated. The original logic in the program to be processed used to call the task interface is updated to control logic executed by the central processing unit to obtain an updated program. The control logic is used by the central processing unit to drive the coprocessor to execute the first executable code. Based on the update program, a second executable code for the central processing unit task is generated on the central processing unit, and the first executable code and the second executable code are encapsulated to obtain the compilation result of the program to be processed.
[0006] This application provides a program compilation apparatus, comprising: An acquisition module is used to acquire a program to be processed, the program to be processed including a central processing unit task executed by the central processing unit and a coprocessor task executed by the coprocessor. An interface module is used to determine from the program to be processed a task interface for instructing the allocation of the coprocessor task to the coprocessor for execution; A generation module is used to generate the first executable code of the coprocessor task on the coprocessor based on the logical relationship of the task interface in the program to be processed; An update module is used to update the original logic in the program to be processed that calls the task interface to the control logic executed by the central processing unit, thereby obtaining an updated program. The control logic is used by the central processing unit to drive the coprocessor to execute the first executable code. An encapsulation module is used to generate a second executable code for the central processing unit task on the central processing unit based on the update program, and to encapsulate the first executable code and the second executable code to obtain the compilation result of the program to be processed.
[0007] This application provides an electronic device, including: Memory is used to store executable instructions or computer programs. The processor, when executing computer-executable instructions or computer programs stored in the memory, implements the compilation method of the program provided in the embodiments of this application.
[0008] This application provides a computer-readable storage medium storing computer-executable instructions or computer programs, which, when executed by a processor, implement the compilation method of the program provided in this application.
[0009] This application provides a computer program product, which includes a computer program or computer-executable instructions stored in a computer-readable storage medium. An electronic device's processor reads the computer-executable instructions or computer program from the computer-readable storage medium and executes the computer-executable instructions or computer program, causing the electronic device to perform the program compilation method described above in this application.
[0010] The embodiments of this application have the following beneficial effects: By acquiring a program containing both CPU and coprocessor tasks and identifying the task interface for task allocation from the program, the system can directly generate the first executable code required by the coprocessor based on the logical relationships of the task interfaces. The original logic in the program that calls the task interface is automatically updated to control logic executed by the CPU. This control logic internalizes the interaction details required to drive the coprocessor to execute the first executable code, thereby reducing the work of manually writing complex logic for low-level data transmission, task initiation, and synchronization. The system generates the second executable code for the CPU based on the updated program containing this control logic and encapsulates the first and second executable codes. This achieves automated conversion from a unified program to the final compiled result. The integrated compilation process avoids the need to maintain independent code for different processors and manually manage interactions between processors, significantly reducing development workload and the possibility of introducing errors, thus effectively improving compilation efficiency. Attached Figure Description
[0011] Figure 1 This is a schematic diagram of the architecture of the compilation system for the program provided in the embodiments of this application; Figure 2 This is a schematic diagram of the structure of an electronic device for compiling programs provided in an embodiment of this application; Figure 3 This is a flowchart illustrating the compilation method of the program provided in the embodiments of this application. Figure 1 ; Figure 4 This is a flowchart illustrating the compilation method of the program provided in the embodiments of this application. Figure 2 ; Figure 5 This is a flowchart illustrating the compilation method of the program provided in the embodiments of this application. Figure 3 ; Figure 6 This is a schematic diagram illustrating the principle of the compilation method of the program provided in the embodiments of this application. Figure 1 ; Figure 7 This is a schematic diagram illustrating the principle of the compilation method of the program provided in the embodiments of this application. Figure 2 ; Figure 8 This is a schematic diagram illustrating the principle of the compilation method of the program provided in the embodiments of this application. Figure 3 ; Figure 9 This is a schematic diagram illustrating the principle of the compilation method of the program provided in the embodiments of this application. Figure 4 . Detailed Implementation
[0012] To make the objectives, technical solutions, and advantages of this application clearer, the application will be further described in detail below with reference to the accompanying drawings. The described embodiments should not be regarded as limitations on this application. All other embodiments obtained by those skilled in the art without creative effort are within the scope of protection of this application.
[0013] In the following description, references are made to “some embodiments,” which describe a subset of all possible embodiments. However, it is understood that “some embodiments” may be the same subset or different subsets of all possible embodiments and may be combined with each other without conflict.
[0014] In the following description, the terms "first, second, third" are used merely to distinguish similar objects and do not represent a specific ordering of objects. It is understood that "first, second, third" may be interchanged in a specific order or sequence where permitted, so that the embodiments of this application described herein can be implemented in an order other than that illustrated or described herein.
[0015] Unless otherwise defined, all technical and scientific terms used herein have the same meaning as commonly understood by one of ordinary skill in the art to which this application belongs. The terminology used herein is for the purpose of describing embodiments of this application only and is not intended to limit this application.
[0016] Before providing a further detailed description of the embodiments of this application, the nouns and terms involved in the embodiments of this application will be explained, and the nouns and terms involved in the embodiments of this application shall be interpreted as follows.
[0017] 1) Central Processing Unit (CPU): The CPU is the core processing unit in a computing device. It is mainly responsible for interpreting computer instructions and processing data in computer software. The CPU usually integrates key components such as control units, arithmetic logic units, and registers to complete instruction fetching, decoding and execution, and to perform arithmetic and logical operations. As the core of general-purpose computing, the CPU can handle a variety of computing tasks and is the foundation for driving the operation of the entire computer system.
[0018] 2) Coprocessor: A coprocessor is an auxiliary processing unit designed to work in conjunction with the central processing unit (CPU) to share the CPU’s specific computational load. Coprocessors are typically hardware-optimized for specialized tasks such as floating-point operations, graphics rendering, or signal processing, and can perform these specific tasks at a higher efficiency than general-purpose CPUs. By offloading these computationally intensive tasks to the coprocessor, application execution can be significantly accelerated, and the CPU can be freed up to handle other system management and control tasks.
[0019] 3) Compilation: This is the process of systematically converting source code written in a high-level programming language into low-level target code or machine instructions that the processor can directly execute. This conversion process is completed by the compiler program, which reads human-readable source code files and goes through multiple stages such as lexical analysis, syntax analysis, semantic analysis, code optimization, and target code generation. Finally, it produces a binary file corresponding to the instruction set of a specific hardware platform. Compilation is performed before program execution, and its goal is to generate executable code that can run efficiently on the target processor.
[0020] During the implementation of the embodiments of this application, the applicant discovered the following problems with the related technology: In related technologies, developers are typically required to write and maintain two separate sets of code for the central processing unit (CPU) and coprocessor. Developers need to use different software development toolchains to compile and generate executable code for the CPU and coprocessor respectively. Developers must also manually write the low-level code for interaction between the two, including complex control logic such as data transfer, task initiation, and execution synchronization. This approach not only increases the complexity and workload of development, but also tightly couples the code to a specific hardware platform. When the hardware platform changes, a lot of code modifications are required, which limits the portability of the program. Furthermore, manually managing the interaction between processors can easily introduce difficult-to-debug concurrent errors, resulting in low compilation efficiency.
[0021] This application provides a method, apparatus, electronic device, computer-readable storage medium, and computer program product for compiling a program, which can effectively improve compilation efficiency. The exemplary application of the program compilation system provided in this application is described below.
[0022] See Figure 1 , Figure 1 This is a schematic diagram of the architecture of the program compilation system 100 provided in the embodiments of this application. The terminal (terminal 400 is shown as an example) connects to the server 200 through the network 300. The network 300 can be a wide area network or a local area network, or a combination of the two.
[0023] Terminal 400 is used by the user to access client 410 and display the compilation results on graphical interface 410-1 (graphical interface 410-1 is shown as an example). Terminal 400 and server 200 are interconnected via wired or wireless network.
[0024] In some embodiments, server 200 can be a standalone physical server, a server cluster or business system composed of multiple physical servers, or a cloud server providing basic cloud computing services such as cloud services, cloud databases, cloud computing, cloud functions, cloud storage, network services, cloud communication, middleware services, domain name services, security services, content delivery networks (CDNs), and big data and artificial intelligence platforms. Terminal 400 can be a smartphone, tablet, laptop, desktop computer, smart speaker, smart TV, smartwatch, in-vehicle terminal, etc., but is not limited to these. The electronic device provided in this application embodiment can be implemented as a terminal or a server. The terminal and server can be directly or indirectly connected via wired or wireless communication, which is not limited in this application embodiment.
[0025] In some embodiments, server 200 obtains a program to be processed, the program including a central processing unit (CPU) task executed by a CPU and a coprocessor task executed by a coprocessor; from the program to be processed, determines a task interface for instructing the allocation of the coprocessor task to the coprocessor for execution; based on the logical relationship of the task interface in the program to be processed, generates a first executable code for the coprocessor task on the coprocessor; updates the original logic in the program to call the task interface to control logic executed by the CPU, obtaining an updated program, the control logic being used by the CPU to drive the coprocessor to execute the first executable code; based on the updated program, generates a second executable code for the CPU task on the CPU, and encapsulates the first executable code and the second executable code to obtain a compilation result of the program to be processed, and sends the compilation result to terminal 400.
[0026] In other embodiments, terminal 400 acquires a program to be processed, the program including a central processing unit (CPU) task executed by a CPU and a coprocessor task executed by a coprocessor; from the program to be processed, a task interface for instructing the allocation of the coprocessor task to the coprocessor for execution is determined; based on the logical relationship of the task interface in the program to be processed, a first executable code of the coprocessor task on the coprocessor is generated; the original logic in the program to call the task interface is updated to control logic executed by the CPU to obtain an updated program, the control logic being used by the CPU to drive the coprocessor to execute the first executable code; based on the updated program, a second executable code of the CPU task on the CPU is generated, and the first executable code and the second executable code are encapsulated to obtain the compilation result of the program to be processed, and the compilation result is sent to server 200.
[0027] As an example, in an application scenario of intelligent image feature extraction, a program to be processed is obtained. This program includes a CPU task (image cropping and data format conversion) executed by the CPU, and a coprocessor task (tensor matrix multiplication and addition operations and activation function processing) executed by the coprocessor. A line-by-line instruction scan is performed on the program to locate function calls to specific tensor computation libraries, identifying the task interface that indicates the allocation of coprocessor tasks to the coprocessor. The data read / write dependencies between matrix multiplication and addition operations and activation function processing are analyzed. Based on the logical relationships of the task interfaces within the program, complex tensor computation operations are converted into low-level machine instruction blocks specific to the coprocessor hardware, generating the first executable code for the coprocessor task on the coprocessor.
[0028] Continuing the previous example, the instruction sequence originally used for intensive mathematical operations in the program to be processed is extracted and replaced with lightweight operations such as sending data transfer instructions to the coprocessor and reading / writing status registers. The original logic used to call the task interface in the program to be processed is updated to control logic executed by the CPU, resulting in an updated program. The control logic is used by the CPU to drive the coprocessor to execute the first executable code. Combining the retained image cropping and conversion operations with the newly introduced control logic, physical register allocation and instruction set mapping are performed. Based on the updated program, the second executable code of the CPU task on the CPU is generated, and the low-level machine instruction blocks required by the coprocessor are hard-coded into the CPU's executable file to establish memory address access mapping. The first and second executable codes are encapsulated to obtain the compiled result of the program to be processed. By stripping away intensive mathematical operations and replacing them with lightweight control logic during the compilation stage, the CPU's computing resource utilization during program execution is kept below a threshold. At the same time, by establishing a direct memory offset access mapping mechanism through unified encapsulation, the cross-device addressing time during program loading and execution is kept below a threshold, ensuring the efficient collaborative operation of heterogeneous computing platforms.
[0029] See Figure 2 , Figure 2 This is a schematic diagram of the structure of an electronic device 500 for compiling programs provided in an embodiment of this application, wherein, Figure 2 The electronic device 500 shown can be Figure 1 Server 200 or terminal 400 in the middle, Figure 2 The illustrated electronic device 500 includes at least one processor 430, a memory 450, and at least one network interface 420. The various components in the electronic device 500 are coupled together via a bus system 440. It is understood that the bus system 440 is used to implement communication between these components. In addition to a data bus, the bus system 440 also includes a power bus, a control bus, and a status signal bus. However, for clarity, ... Figure 2 The general labeled all buses as Bus System 440.
[0030] Processor 430 can be an integrated circuit chip with signal processing capabilities, such as a general-purpose processor, a digital signal processor (DSP), or other programmable logic devices, discrete gate or transistor logic devices, discrete hardware components, etc. Among them, the general-purpose processor can be a microprocessor or any conventional processor, etc.
[0031] The memory 450 may be removable, non-removable, or a combination thereof. Exemplary hardware devices include solid-state storage, hard disk drives, optical disk drives, etc. The memory 450 may optionally include one or more storage devices physically located away from the processor 430.
[0032] The memory 450 may include volatile memory or non-volatile memory, or both. The non-volatile memory may be read-only memory (ROM), and the volatile memory may be random access memory (RAM). The memory 450 described in this application embodiment is intended to include any suitable type of memory.
[0033] In some embodiments, memory 450 is capable of storing data to support various operations, examples of which include programs, modules, and data structures or subsets or supersets thereof, as illustrated below.
[0034] Operating system 451 includes system programs for handling various basic system services and performing hardware-related tasks, such as the framework layer, core library layer, driver layer, etc., for implementing various basic business functions and handling hardware-based tasks; The network communication module 452 is used to reach other electronic devices via one or more (wired or wireless) network interfaces 420, such as Bluetooth, WiFi, and Universal Serial Bus.
[0035] In some embodiments, the program compilation apparatus provided in this application can be implemented in software. Figure 2 A compilation device 455 for a program stored in memory 450 is shown. This program can be software in the form of programs and plugins, and includes the following software modules: an acquisition module 4551, an interface module 4552, a generation module 4553, an update module 4554, and an encapsulation module 4555. These modules are logically related and can therefore be arbitrarily combined or further divided according to the functions they implement. The functions of each module will be described below.
[0036] In other embodiments, the program compilation apparatus provided in this application can be implemented in hardware. As an example, the program compilation apparatus provided in this application can be a processor in the form of a hardware decoding processor, which is programmed to execute the program compilation method provided in this application. For example, the processor in the form of a hardware decoding processor can be one or more application-specific integrated circuits (ASICs), DSPs, programmable logic devices (PLDs), complex programmable logic devices (CPLDs), field-programmable gate arrays (FPGAs), or other electronic components.
[0037] In some embodiments, the terminal or server can implement the compilation method of the program provided in this application by running a computer program or computer-executable instructions. For example, the computer program can be a native program in the operating system (e.g., a dedicated compiler) or a software module, such as a compiled module that can be embedded in any program (e.g., an instant messaging client, a photo album program, an electronic map client, a navigation client); for example, it can be a native application (APP), that is, a program that needs to be installed in the operating system to run. In summary, the above-mentioned computer program can be any form of application, module, or plugin.
[0038] The compilation method of the program provided in the embodiments of this application will be described in conjunction with exemplary applications and implementations of the server or terminal provided in the embodiments of this application.
[0039] See Figure 3 , Figure 3 This is a flowchart illustrating the compilation method of the program provided in the embodiments of this application. Figure 1 , will combine Figure 3 Steps 101 to 105 are described below. The program compilation method provided in this application embodiment can be implemented by the server or the terminal alone, or by the server and the terminal working together. The following description will take the implementation by the server alone as an example.
[0040] In step 101, a program to be processed is obtained, which includes a central processing unit task executed by the central processing unit and a coprocessor task executed by the coprocessor.
[0041] In some embodiments, the process of obtaining the program to be processed is the starting point of the entire compilation and conversion process. The program to be processed refers to the set of original code that has not yet been deeply optimized and separately compiled for a specific hardware architecture. The program to be processed is usually written in a high-level programming language. The central processing unit (CPU) usually refers to a general-purpose processor with general computing capabilities and complex logic control capabilities. The coprocessor usually refers to a dedicated processor that performs hardware acceleration for specific types of computing tasks. The CPU task refers to the logic branch code and scalar operation code in the program to be processed that are suitable for running on the CPU. The coprocessor task refers to the matrix operation code and parallel computing code in the program to be processed that are suitable for running on the coprocessor.
[0042] In some embodiments, the specific methods for obtaining the program to be processed include reading source code files from local storage media, or receiving intermediate representation text transmitted externally via a network interface. The program to be processed is usually written using a unified programming framework in its initial state. Developers do not need to pay attention to the specific physical topology of the underlying hardware when writing the program to be processed. The program to be processed internally includes both central processing unit tasks and coprocessor tasks. This hybrid writing method reduces the complexity of code writing and makes the logical structure of the program to be processed more compact.
[0043] In some embodiments, after obtaining the program to be processed, lexical analysis and syntax analysis are required. The program to be processed is transformed into an intermediate code representation through an abstract syntax tree. In the intermediate code representation, the boundaries between central processing unit (CPU) tasks and coprocessor tasks can be initially distinguished. For example, when a matrix multiplication operation with a nested loop level greater than a threshold is detected, it is classified as a coprocessor task. When a control flow statement with a conditional branch complexity greater than a threshold is detected, it is classified as a CPU task. This preliminary analysis based on the syntax tree and complexity threshold provides basic data support for subsequent heterogeneous compilation separation.
[0044] In some embodiments, a program to be processed, including central processing unit tasks and coprocessor tasks, is obtained, enabling the compilation front-end to obtain a complete overview of the business logic. This complete overview of the business logic includes the data flow direction and control dependencies between different computing tasks. Based on these complete data flow directions and control dependencies, global resource allocation and instruction scheduling can be performed in the subsequent compilation process, avoiding increased data transmission latency caused by local compilation, thereby improving the overall running efficiency of the final executable file on heterogeneous chips.
[0045] In step 102, a task interface for instructing the coprocessor task to be assigned to the coprocessor for execution is determined from the program to be processed.
[0046] In some embodiments, determining the task interface from the program to be processed, which is used to indicate the allocation of coprocessor tasks to the coprocessor for execution, is a key prerequisite for achieving heterogeneous computing task separation. The program to be processed contains mixed computing logic, and the task interface refers to the abstract boundary identifier defined inside the program to be processed. The task interface is used to isolate the execution code of different hardware architectures at the logical level. The task interface represents the entry point for the transfer of computing control from the central processing unit to the coprocessor. By determining the task interface, the start and end positions of the coprocessor tasks can be accurately located.
[0047] In some embodiments, the process of determining the task interface is essentially a process of logical semantic parsing of the program to be processed. In a program to be processed in a hybrid manner, the central processing unit task and the coprocessor task usually have a complex intertwined relationship. As a declarative specification, the task interface carries the data input and output definitions and execution configuration information required by the coprocessor task. By extracting the declarative specification, the coprocessor task that was originally coupled to the main control flow can be separated to form an independent schedulable unit, so that the subsequent compilation process can generate instructions for a specific hardware architecture for the separated schedulable unit.
[0048] In some embodiments, a task interface is determined for instructing the allocation of coprocessor tasks to coprocessors for execution. This enables the compilation process to accurately perceive the heterogeneous computing intent within the program to be processed. Accurate perception of heterogeneous computing intent avoids compiling all code into central processing unit instructions. Avoiding unified compilation prevents the coprocessor from being idle. Preventing coprocessor idleness allows coprocessor tasks with computational loads exceeding a threshold to be accurately offloaded to the coprocessor for accelerated processing. Through precise task offloading, the parallel computing advantages of the coprocessor are fully utilized, thereby improving the overall execution efficiency of the program to be processed on heterogeneous hardware platforms.
[0049] In some embodiments, see Figure 4 , Figure 4 This is a flowchart illustrating the compilation method of the program provided in the embodiments of this application. Figure 2 , Figure 3 Step 102 shown can be achieved through Figure 4 Steps 1021 to 1023 shown are implemented.
[0050] In step 1021, the program to be processed is converted into code to obtain the first reference code of the program to be processed.
[0051] In some embodiments, during the code transformation of the program to be processed to obtain the first reference code, a front-end compiler performs lexical and syntactic analysis on the source code of the program to be processed, mapping the logical structure described by the high-level programming language into an intermediate representation. This intermediate representation is the first reference code, which is platform-independent and retains the complete control flow and data flow information of the original program. The first reference code can adopt a low-level virtual machine intermediate representation, which can transform complex source code function calls into instruction flows composed of basic blocks, facilitating subsequent fine-grained instruction scanning and feature extraction, thereby providing a unified code foundation for distinguishing heterogeneous tasks.
[0052] In some embodiments, code transformation utilizes an abstract syntax tree to refactor program logic, converting abstract algorithms written by developers into linear instruction sequences that more closely resemble hardware execution logic. Each instruction in the first reference code carries opcode and operand information, clearly reflecting the program's computational intent and memory access characteristics during execution. Through this transformation method, the previously intertwined task logic is standardized into standard intermediate instructions, freeing the subsequent automated identification process from the syntactic diversity of the source code. The first reference code includes not only ordinary scalar arithmetic operations but also function call stubs for specific hardware acceleration libraries, providing crucial clues for accurately locating coprocessor tasks.
[0053] In step 1022, the instruction sequence executed by the central processing unit is identified from the first reference code, and the instruction sequence is detected to obtain a detection result.
[0054] In some embodiments, when identifying and detecting instruction sequences executed by the central processing unit (CPU) from the first reference code, the set of instructions scheduled and executed by the CPU is extracted by traversing all basic instruction blocks in the first reference code. These instruction sequences cover basic operations such as branch jumps, register loading, and scalar addition and subtraction. During the detection of the instruction sequences, each opcode in the instruction sequence is scanned using an instruction pattern matching algorithm or a feature string search algorithm to determine whether a predefined special instruction is embedded within it. The process of obtaining the detection result is essentially an attribute marking process. The detection result reflects whether there are symbolic references or external link requests with specific meanings in the instruction sequence. This information is the core basis for determining task attributes.
[0055] In some embodiments, identification and detection leverage the semantic features of the CPU instruction set to separate ordinary logic control flow from potential accelerated computing requests. The instruction sequence executed by the CPU typically forms the backbone of the program, driving the entire software lifecycle. The detection process can focus on application programming interface calls with specific prefixes or namespaces, including these calls and their associated upstream and downstream instruction contexts. The resulting detection result, as a Boolean value or enumerated state, explicitly informs subsequent processing stages whether the current instruction sequence has triggered hardware coordination mechanisms, thereby achieving the goal of rapidly filtering key control points from a massive number of basic instructions.
[0056] In step 1023, when the detection result indicates that there is a target invocation instruction in the instruction sequence for invoking the coprocessor, the target invocation instruction is marked as the task interface.
[0057] In some embodiments, when the detection result indicates the presence of a target call instruction for invoking a coprocessor in the instruction sequence, marking the target call instruction as a task interface enables the extraction of key anchor points from the general instruction stream. A target call instruction refers to a specific instruction in the program to be processed that is specifically responsible for initiating heterogeneous computing requests; it carries the type information and parameter pointers of the computing task. By marking these instructions as task interfaces, the compiler can establish transition points for task migration from the central processing unit to the coprocessor within a complex program graph. The marking process can be accomplished by adding specific metadata tags to the attribute fields of the intermediate representation. These metadata tags can instruct subsequent compiler iterations to perform specific logical substitutions and code generation at that location.
[0058] In some embodiments, marking task interfaces establishes a mapping relationship, transforming software-level functional requirements into hardware-level scheduling entry points. Since the target invocation instruction itself represents a high-density computational requirement, identifying and marking it as a task interface allows the compiler to extract the computational logic behind that interface in subsequent processes. The task interface not only records the physical location of the target invocation instruction but also records the tensor dimension information and data type constraints involved in the instruction. This marking mechanism ensures that the program can accurately identify the computational load that needs to be redirected to the coprocessor while maintaining logical continuity, providing structured data support for the automatic partitioning and optimization of heterogeneous computing.
[0059] Thus, by generating a first reference code with unified semantics through code conversion, the parsing difficulties caused by directly processing heterogeneous source code are avoided, improving the stability of the identification process. By performing fine-grained detection of instruction sequences and marking task interfaces, computationally intensive tasks can be extracted from complex control flows. The derivation logic of this process lies in transforming the heterogeneous programming pattern, which originally required manual decomposition, into an interface marking pattern automatically perceived by the compiler, reducing the risk of errors caused by human intervention. Ultimately, guided by the task interface, the coprocessor can efficiently undertake specific computations, reducing the instruction issuance burden on the central processing unit, thereby improving the overall execution efficiency of the program on heterogeneous hardware.
[0060] In step 103, based on the logical relationship of the task interface in the program to be processed, the first executable code of the coprocessor task on the coprocessor is generated.
[0061] In some embodiments, the process of generating the first executable code of the coprocessor task on the coprocessor based on the logical relationships between task interfaces in the program to be processed first involves a deep analysis of the contextual relationships between task interfaces. The logical relationships in the program to be processed are manifested in the sequential order of the various task interfaces in terms of timing, and the dependency paths in terms of data transfer. By analyzing these logical relationships, the sources of data input required by the coprocessor task during execution and the destination of the computation results can be determined, thereby constructing a computational topology that conforms to the semantics of the original program. In this process, by detecting the definition and usage links of variables in the program to be processed, the scattered task interfaces can be linked together to form a complete computational subgraph or computational flow, ensuring that the generated code accurately reflects the developer's expected business logic, while also clarifying which data needs to be synchronized or transferred between the central processing unit and the coprocessor.
[0062] In some embodiments, after establishing the logical relationships of the task interface, the next focus is on transforming these abstract logical descriptions into instructions that the hardware can directly understand. The process of generating the first executable code is essentially a compilation and mapping process specific to a particular hardware architecture. By extracting the mathematical operations or logical processing functions covered by the task interface and combining them with the instruction set architecture characteristics of the coprocessor, the operational logic described in the high-level language is translated into a sequence of low-level machine instructions. This process not only includes the direct translation of instructions but also implicitly involves the static scheduling of coprocessor hardware resources, such as register allocation, on-chip memory planning, and pipelined arrangement of parallel computing units. Through this transformation, the heterogeneous computing requests originally embedded in the program to be processed are materialized into an independent block of binary code that can be loaded and executed by the coprocessor.
[0063] In some embodiments, logical relationships refer to the mutual constraints between various instructions or code blocks in the program to be processed within the execution flow. These mainly include control flow dependencies, meaning whether a task is executed depends on the result of the previous task, and data flow dependencies, meaning whether the input data of a task originates from the output of the previous task. The first executable code refers to a binary program segment specifically generated for the coprocessor, containing specific arithmetic instructions and operands. Its format matches the hardware decoding circuitry of the coprocessor and is typically incompatible with the instruction set of the central processing unit. The first executable code carries the computationally intensive core load of the program to be processed.
[0064] In some embodiments, see Figure 5 , Figure 5 This is a flowchart illustrating the compilation method of the program provided in the embodiments of this application. Figure 3 , Figure 3 Step 103 shown can be achieved through Figure 5 Steps 1031 to 1034 shown are implemented.
[0065] In step 1031, the calling order of each task interface in the program to be processed is parsed, and the data dependency relationship between the task interfaces is determined according to the transmission relationship between the input parameters and output parameters of the task interfaces.
[0066] In some embodiments, the task interface includes a first task interface and a second task interface. Determining the data dependency relationship between the task interfaces based on the transmission relationship between their input and output parameters can be achieved as follows: obtaining the output parameter set of the first task interface and the input parameter set of the second task interface; when the output parameter set of the first task interface intersects with the input parameter set of the second task interface, determining the directed edges in the task graph structure from the node corresponding to the first task interface to the node corresponding to the second task interface as the data dependency relationship between the first and second task interfaces.
[0067] In some embodiments, when determining the data dependencies between task interfaces, the parameter information involved in the execution of different task interfaces is extracted by parsing the data flow in the program to be processed. The task interfaces include a first task interface and a second task interface, which represent two heterogeneous task call points that appear sequentially in the program to be processed. The output parameter set of the first task interface is obtained, which contains all result variables or memory address information generated after the first task interface is executed. Simultaneously, the input parameter set of the second task interface is obtained, which contains the initial variables or operands that the second task interface must depend on when it starts execution. This parameter set acquisition process is based on the compiler's static scanning of the program variable lifecycle, ensuring that all possible data interaction paths are covered.
[0068] In some embodiments, establishing data dependencies essentially involves identifying the producer-consumer relationship during program execution. When the output parameter set of the first task interface intersects with the input parameter set of the second task interface, it means that the data calculated by the first task interface is the material basis for the normal operation of the second task interface, and there is a clear data transmission link between the two task interfaces. In this case, a directed edge is established in the task graph structure reflecting the program's logical structure, pointing from the corresponding node of the first task interface to the corresponding node of the second task interface. This directed edge explicitly expresses the data dependency relationship. The intersection comparison of parameter sets can be achieved using hash value matching or by detecting whether the two interfaces reference the same memory pointer. As long as at least one parameter overlaps, a data dependency is determined to exist.
[0069] In some embodiments, nodes represent the computational load in the program to be processed, while directed edges represent the execution constraints of the computational tasks. Once the data dependencies between the first and second task interfaces are determined, the directed edge not only indicates the order of execution but also carries quantitative information about data movement. If the intersection elements of the parameter sets are detected to be large-scale tensor data, the directed edge can be further associated with data movement instructions to guide the subsequent first executable code to incorporate necessary memory synchronization operations during generation. Through this topological description, complex program logic is transformed into a mathematically meaningful directed acyclic graph, providing structured data support for subsequent parallelism analysis and resource scheduling, and ensuring data consistency during the execution of heterogeneous computing tasks.
[0070] Thus, by extracting parameter sets and determining their intersections to identify data dependencies, the accuracy and automation of heterogeneous program compilation can be significantly improved. Because a criterion based on the intersection of parameter sets is used, the true producer-consumer relationships between task interfaces can be accurately identified, avoiding parallelism limitations caused by spurious dependencies. By establishing directed edges in the task graph structure, hidden data dependencies are transformed into intuitive topological constraints. The resulting technical effect is that the compiler can generate first executable code that strictly conforms to sequential logic, ensuring that the coprocessor does not experience data read / write conflicts during large-scale parallel computing. This definite dependency provides a basis for memory resource reuse, reduces redundant data copying overhead, and thus maximizes the computational performance of heterogeneous systems while ensuring logical correctness.
[0071] In step 1032, a task graph structure is constructed to describe the execution task flow of the coprocessor task based on the calling order and the data dependencies.
[0072] In some embodiments, constructing a task graph structure is a core step in visualizing and managing the coprocessor task execution logic. A task graph structure is a directed acyclic graph (DAG), where each node represents an independent coprocessor task interface, and each edge represents a data dependency or control flow order relationship between task interfaces. By mapping call order information to the topological ordering relationship between nodes in the task graph structure, and mapping data dependencies to data flow edges between nodes, a complete task execution flow graph is formed.
[0073] In some embodiments, the task graph structure can be represented using an adjacency matrix or an adjacency list. Each task interface is abstracted as a graph node, and the node's attributes can include a unique identifier for the task interface, a list of input parameters, a list of output parameters, and the expected execution time. When it is detected that the output parameter of task interface A is the input parameter of task interface B, a directed edge is added between the node corresponding to task interface A and the node corresponding to task interface B, indicating that data flows from task interface A to task interface B. When there is a strict sequential execution order between task interfaces, but no direct data dependency, control dependency edges can also be added to represent this sequential relationship.
[0074] In step 1033, the nodes in the task graph structure are mapped to reference operators, and the connection relationships between the nodes in the task graph structure are mapped to data index relationships between the reference operators.
[0075] In some embodiments, mapping nodes in the task graph structure to reference operators concretizes the abstract coprocessor task interface into executable computational units. Reference operators are predefined or configurable basic computational operation units on the coprocessor, each corresponding to one or more efficient hardware acceleration functions on the coprocessor. This mapping process translates the high-level semantic task interface into low-level hardware-recognizable computational primitives, thereby providing standardized building blocks for subsequent code generation.
[0076] In some embodiments, the mapping process is typically accomplished by querying a predefined operator library or operator mapping table. For example, when a node in the task graph structure represents a matrix multiplication task interface, it is mapped to the corresponding matrix multiplication reference operator on the coprocessor. When a node represents a convolution operation task interface, it is mapped to the corresponding convolution reference operator on the coprocessor. Mapping the connection relationships between nodes in the task graph structure to data index relationships between reference operators means specifying the specific memory addresses or register indices for data transfer between different reference operators. For example, if the output data of reference operator A is the input data of reference operator B, then the data index relationship specifies the data storage location of the output data of reference operator A and where reference operator B reads this data from.
[0077] In step 1034, the first executable code of the coprocessor task on the coprocessor is generated according to the topological order of the task graph structure, based on the data index relationship between the reference operators and the reference operators.
[0078] In some embodiments, the generation of the first executable code of the coprocessor task on the coprocessor based on the data index relationship between the reference operators and the reference operators, according to the topological order of the task graph structure, can be implemented as follows: Based on the data index relationship between the reference operators, the reference operators are updated to obtain the target operators; static memory planning is performed on the data objects associated with the data index relationship between the target operators to obtain the physical storage address of the data objects in the coprocessor memory; the target operators are converted into machine instructions supported by the coprocessor, and the physical storage address is written into the operand field of the machine instructions to obtain the first executable code.
[0079] In some embodiments, updating reference operators based on data index relationships between them to obtain target operators is a crucial step in combining abstract computational units with specific data flow contexts. Reference operators are general descriptions of computational operations, while target operators are specific descriptions of computational operations incorporating particular data formats and storage layout information. Data index relationships clarify the type and dimensions of data objects passed between reference operators. Updating reference operators using this information—for example, selecting an operator implementation optimized for a specific data type—generates a target operator that better matches the hardware characteristics. At the underlying implementation level, the update process may include updating a floating-point reference operator to a fixed-point target operator based on the quantization type of the input data object, or updating a general memory access reference operator to a target operator using burst transfer mode based on the memory contiguity of the input data object. This update allows subsequent instruction generation to leverage the specific hardware acceleration features of the coprocessor.
[0080] In some embodiments, static memory planning is performed on the data objects associated with the data index relationships between target operators. This aims to predetermine the storage locations of all intermediate data and final results in the coprocessor memory during the compilation phase. Static memory planning avoids the overhead and uncertainty of dynamic memory allocation during program runtime, thereby improving execution efficiency and stability. By analyzing the lifecycle of all data objects—that is, the creation time and the last time they were used—memory reuse can be achieved. Multiple data objects with non-overlapping lifecycles can be planned into the same physical memory region, thus reducing the overall memory capacity requirements of the coprocessor task. At the underlying implementation level, static memory planning can employ memory pooling technology. A contiguous memory space is pre-allocated in the coprocessor memory, and then, through lifecycle analysis algorithms and memory alignment strategies, the physical storage address of each data object in the memory pool is calculated, ultimately generating a complete mapping table from data object identifiers to physical storage addresses.
[0081] In some embodiments, converting the target operator into machine instructions supported by the coprocessor and writing the physical storage address into the operand field of the machine instructions is the final step in generating the final executable binary file. After this step, the target operator is translated into a sequence of low-level instructions that the coprocessor can directly decode and execute. The physical storage address is directly hard-coded into the machine instructions, allowing the coprocessor to directly access data at a specified memory location without any address translation or table lookup operations, thus greatly improving data access efficiency. At the underlying implementation level, this process is typically performed by a compiler backend or code generator. The code generator maintains one or more instruction templates for each target operator, selects an appropriate instruction template based on the specific parameters of the target operator, and then fills the physical storage address obtained in the static memory planning stage into the operand field of the instruction template. Finally, all the machine instructions generated by the target operators are linked together according to the topological order of the task graph structure to form the first executable code of the complete coprocessor task.
[0082] Thus, by performing static memory planning on data objects during the compilation phase, the physical storage addresses of all data objects in the coprocessor's memory are pre-determined. This avoids the need for dynamic memory allocation during program runtime, thereby eliminating the system overhead of runtime memory management and the uncertainty of execution time. These pre-calculated physical storage addresses are directly written into the operand fields of machine instructions, allowing the coprocessor to skip the intermediate steps of address lookup and translation when executing the first executable code, directly retrieving data through a single memory access operation. This direct address access method reduces processor wait cycles and lowers memory access latency because the coprocessor does not need to interact with the operating system or memory management unit. Therefore, when the final generated first executable code is executed on the coprocessor, data access efficiency is significantly improved, thereby enhancing the overall computational performance of the coprocessor task and strengthening the real-time performance and determinism of task execution.
[0083] In some embodiments, the static memory planning of the data objects associated with the data index relationship between the target operators to obtain the physical storage address of the data objects in the coprocessor memory can be implemented as follows: Determine the lifecycle and required memory size of each data object according to the topological order of the target operators; determine the memory offset of each data object based on the lifecycle and memory size, the memory offset indicating the starting position of the data object in the coprocessor memory; determine the physical storage address of the data object in the coprocessor memory according to the preset base address of the coprocessor memory and the memory offset of each data object.
[0084] In some embodiments, during the static memory planning of data objects associated with the data index relationships between target operators, it is first necessary to clarify the attributes of each data object in the time and spatial dimensions. Following the topological order of the target operators, the time of creation and the time of last use of each data object can be identified; the time span between these two times constitutes the lifecycle of the data object. Simultaneously, based on the data type and tensor shape information of the data object, the memory size required to store the data object can be accurately calculated. The topological order can be determined by performing a breadth-first or depth-first traversal of the operator dependency graph. The lifecycle can be represented as a time step or instruction index interval, and the memory size is calculated by multiplying each dimension by the number of bytes of a single element.
[0085] In some embodiments, based on a defined lifecycle and memory size, a memory offset is allocated to each data object using a memory allocation algorithm, assigning a relative position (i.e., a memory offset) relative to the starting point of memory. The core of this process is to reuse memory space as much as possible; that is, when the lifecycles of two data objects do not overlap on the timeline, they are allowed to share the same memory region. This reuse mechanism ensures that the peak total memory required for the computational task is less than a threshold, thus adapting to the limited on-chip storage resources of the coprocessor. Greedy algorithms, first-fit algorithms, or best-fit algorithms can be used to allocate memory offsets. Memory alignment constraints can also be introduced during the allocation process to ensure that the calculated memory offset meets the alignment requirements for hardware reads, such as 16-byte alignment or 64-byte alignment.
[0086] In some embodiments, relative memory offsets are converted into absolute physical addresses that the coprocessor can directly address. Based on the coprocessor's memory hardware specifications, the starting address of a contiguous block of memory reserved for data objects is determined, i.e., a preset base address. The physical storage address of the data object in the coprocessor's memory is obtained by adding the memory offset of each data object to this preset base address. This static address binding method ensures that the storage location of each piece of data is determined before program execution. This step typically occurs during the compiler's backend code generation phase, and the calculated physical storage address is directly encoded into the operands of the coprocessor's load or store instructions, eliminating the need for dynamic address translation at runtime.
[0087] Thus, the precise storage location of data on the coprocessor is determined during the compilation phase. By combining lifecycle and memory size analysis, the determination of memory offsets fully considers time reusability, effectively reducing peak memory usage during coprocessor task execution. The physical storage address is obtained by calculating the base address and offset, eliminating the time overhead and uncertainty caused by runtime dynamic memory allocation. This technical derivation shows that static planning can avoid memory fragmentation problems, and because the address is known, the hardware can directly access data through the physical address without the need for complex memory management units, thereby significantly improving the bandwidth utilization and overall computational efficiency of the coprocessor when reading data.
[0088] Thus, by parsing the task interface call order and data dependencies in the program to be processed, and constructing a task graph structure, the originally complex and intertwined coprocessor tasks can be clearly logically divided and structurally represented. This structured representation makes the subsequent process of mapping task graph nodes to reference operators and generating the first executable code more efficient and accurate. Clear data dependencies and call order ensure that the generated first executable code of the coprocessor task can correctly handle data flow during execution, avoiding pauses or errors caused by incomplete data. Simultaneously, mapping nodes in the task graph structure to reference operators on the coprocessor fully utilizes the characteristics of the coprocessor's hardware acceleration unit, enabling each coprocessor task to execute in its most efficient manner. The first executable code generated according to the topological order maximizes the coprocessor's parallel computing capabilities, reduces task switching overhead, and thus significantly improves the overall performance of the program to be processed on the heterogeneous computing platform, reduces power consumption, and shortens task completion time.
[0089] In step 104, the original logic in the program to be processed used to call the task interface is updated to control logic executed by the central processing unit to obtain an updated program. The control logic is used by the central processing unit to drive the coprocessor to execute the first executable code.
[0090] In some embodiments, updating the original logic in the program to be processed, which is used to call the task interface, to control logic executed by the central processing unit (CPU) to obtain an updated program is a key step in realizing the collaborative work of heterogeneous processors. The original logic refers to the code fragment in the program to be processed that makes high-level abstract calls to the coprocessor task. This calling method only indicates the execution intention and does not involve the interaction details of the underlying hardware. The control logic refers to a set of low-level instruction sequences executed by the CPU to manage and drive the coprocessor to execute specific tasks. The updated program is the main program that finally runs on the CPU. It contains the original CPU task and the newly generated control logic.
[0091] In some embodiments, the essence of the update process is to replace an abstract function call feature with a specific hardware driver feature. The control logic, acting as a bridge between the central processing unit (CPU) and the coprocessor, encapsulates all necessary interactive operations such as starting the coprocessor, passing data addresses, and synchronizing execution status. By replacing the original logic with the control logic, the program to be processed is transformed from a logically unified program into a physically separated program. The update program runs as the master on the CPU, while the first executable code runs as the controlled on the coprocessor. The two cooperate through a communication mechanism established by the control logic.
[0092] In some embodiments, the original logic used to call the task interface is updated to control logic executed by the central processing unit (CPU). This enables the CPU to schedule and manage coprocessor resources in an efficient and direct manner. The original logic typically requires complex runtime system parsing and scheduling, which introduces additional execution overhead and latency. The replaced control logic is tailored to a specific coprocessor and a specific first executable code. It contains instructions that directly manipulate hardware registers or call the underlying driver interface. This direct control method bypasses the general runtime system, greatly shortening the time interval between the CPU issuing the task instruction and the coprocessor starting to execute the first executable code, thereby significantly improving the overall response speed and execution efficiency of heterogeneous computing.
[0093] In some embodiments, step 104 above can be implemented as follows: identifying a sequence of arithmetic instructions for executing the function of the task interface from the program to be processed, and determining the sequence of arithmetic instructions as the original logic; constructing an interactive instruction sequence for driving the coprocessor to execute the first executable code based on the calling specification of the first executable code, and determining the interactive instruction sequence as the control logic; replacing the original logic in the program to be processed with the control logic to obtain the updated program.
[0094] In some embodiments, during the migration of a program to a heterogeneous computing platform, updating the original logic used to call the task interface to control logic executed by the central processing unit (CPU) first involves a deep analysis of the existing code structure. Identifying the sequence of arithmetic instructions used to execute the task interface functions from the program aims to locate computationally intensive or logically complex code segments and identify them as the original logic. This original logic typically contains numerous mathematical operations, loop structures, or conditional branches, which would consume a significant number of clock cycles if executed directly by the CPU. Static code analysis techniques can be used to traverse the abstract syntax tree or intermediate representation of the program to find call nodes matching specific task interface function names, or by analyzing the opcode characteristics of instructions to identify assembly instruction segments that conform to specific operator characteristics, thereby precisely defining the boundaries of the code that needs to be unloaded.
[0095] In some embodiments, after determining the original logic that needs to be replaced, constructing the control logic capable of driving the coprocessor is the core step. Based on the calling specification of the first executable code, an interactive instruction sequence is constructed to drive the coprocessor to execute the first executable code, and this interactive instruction sequence is identified as the control logic. This process needs to follow the hardware interface definition of the coprocessor and generate instruction code that conforms to its communication protocol. The calling specification may involve specific register configuration rules, parameter setting formats of the direct memory access controller, or interrupt triggering mechanisms. The specific content of the interactive instruction sequence includes writing the memory address of the input data into the coprocessor's base address register, configuring operation parameters such as convolution kernel size or stride, and sending a start signal to activate the coprocessor's arithmetic unit. These instructions are few in number and execute quickly compared to the original arithmetic instructions.
[0096] In some embodiments, after the control logic is constructed, a code replacement operation is performed to generate the final updated program. Replacing the original logic in the program to be processed with control logic means that the heavy computational tasks originally undertaken by the central processing unit are removed from the program's execution flow, and replaced by lightweight scheduling instructions. This replacement process ensures the equivalence of program functionality; that is, given the same input, the output obtained by calling the coprocessor remains consistent with the original program. This typically occurs during the compiler's backend optimization or linking stage, by modifying the binary code of the object file, overwriting the original function body content with a newly generated sequence of interactive instructions, or modifying the jump address of function calls to point to a new code segment containing control logic, thereby completing the generation of heterogeneous code.
[0097] Thus, the original logic typically contains highly complex and time-consuming computational instructions, while the control logic contains only a small number of configuration and startup instructions, with the number of instructions and execution cycles far less than the threshold. Therefore, when the updated program runs, the CPU utilization decreases significantly, allowing more time slices to be allocated to operating system scheduling or user interaction tasks. Simultaneously, this mechanism enables the general-purpose processor and dedicated coprocessor to form a parallel pipeline, avoiding CPU blocking caused by executing long-running tasks, thereby significantly improving throughput and energy efficiency.
[0098] In some embodiments, the above-described interactive instruction sequence for driving the coprocessor to execute the first executable code, based on the calling specification of the first executable code, can be implemented as follows: Based on the input parameter passing mechanism defined in the calling specification of the first executable code, a data preparation instruction is constructed, which instructs the central processing unit (CPU) to transfer the input data required for executing the coprocessor task from the CPU memory space to the coprocessor memory space; based on the task startup protocol defined in the calling specification of the first executable code, a task startup instruction is constructed, which instructs the CPU to write the entry address of the first executable code on the coprocessor into a designated control register of the coprocessor to trigger the coprocessor to start execution; based on the task completion and result return protocol defined in the calling specification of the first executable code, an execution synchronization instruction is constructed, which instructs the CPU to poll the status register of the coprocessor to retrieve the output data of the coprocessor task from the coprocessor memory space after learning that the coprocessor has completed execution; the data preparation instruction, the task startup instruction, and the execution synchronization instruction are then constructed into the interactive instruction sequence.
[0099] In some embodiments, based on the input parameter passing mechanism defined in the calling specification of the first executable code, data preparation instructions are constructed. These instructions are a set of operations executed by the CPU to safely and accurately migrate all necessary input data from CPU-accessible storage space to coprocessor-accessible storage space before the coprocessor begins executing computational tasks. The input parameter passing mechanism specifies in detail the identifier of the data object to be transferred, the data size, and the target storage layout, ensuring correct mapping of data between different processor storage domains. At the underlying implementation level, constructing data preparation instructions typically generates a series of instructions for configuring the direct memory access controller. These instructions write the source physical address of the input data in the CPU storage space, the target physical address in the coprocessor storage space, and the number of bytes to be transferred into the corresponding registers of the direct memory access controller. Finally, a single instruction triggers the direct memory access controller to start background data transfer, thereby completing data preparation without consuming CPU computing resources.
[0100] In some embodiments, a task startup instruction is constructed based on the task startup protocol defined in the calling specification of the first executable code. This task startup instruction is an explicit execution signal issued by the CPU to the coprocessor, used to activate the coprocessor in standby mode and instruct it to fetch and execute instructions starting from the specified entry address of the first executable code. The task startup protocol defines the hardware conditions and operation sequence that must be met to trigger coprocessor execution, such as which specific value needs to be written to which specific control register. At the underlying implementation level, constructing the task-start instruction typically generates one or more memory-mapped write operation instructions. By executing these write instructions, the CPU writes the starting physical address of the first executable code in the coprocessor's memory to a predefined program counter load register or command register of the coprocessor. The write operation to this specific register is captured by the coprocessor's control logic unit and parsed into a command to start execution, thereby waking up the coprocessor and starting to execute the first executable code.
[0101] In some embodiments, based on the task completion and result return protocol defined in the calling specification of the first executable code, execution synchronization instructions are constructed, and data preparation instructions, task initiation instructions, and execution synchronization instructions are combined into an interactive instruction sequence. The execution synchronization instructions are used to solve the asynchronous execution problem between the central processing unit (CPU) and the coprocessor, ensuring that the CPU can perform subsequent operations or retrieve computation results only after the coprocessor has completed its task. The task completion and result return protocol specifies how the coprocessor notifies the CPU that its task has been completed and the location of the output data. At the underlying implementation level, constructing the execution synchronization instructions typically generates a polling loop. In this loop, the CPU repeatedly reads a specific status register of the coprocessor and checks whether a certain flag bit has been set to the task completion state by the coprocessor. Once task completion is detected, the CPU exits the loop and, according to the result return protocol, initiates another direct memory access operation to transfer the output data from the coprocessor's memory space back to the CPU's memory space. Finally, the sequentially arranged data preparation instructions, task initiation instructions, and execution synchronization instructions are combined into a complete code block, i.e., the interactive instruction sequence.
[0102] In this way, by solidifying low-level hardware interaction operations such as data preparation, task initiation, and execution synchronization into a set of deterministic interactive instruction sequences, replacing the original high-level abstract call logic, this approach avoids relying on general-purpose operating system schedulers or complex driver interfaces for task dispatch during program runtime. General-purpose runtime systems typically introduce overheads such as context switching, interrupt handling, and dynamic resource allocation, which increase the latency and make the timing of task scheduling uncertain. The constructed interactive instruction sequence, however, is optimized for specific hardware and specific tasks. It directly operates on hardware registers, bypassing these high-overhead software layers, thereby significantly reducing the time latency from task initiation by the central processing unit to the start of execution by the coprocessor. This reduces the interaction cost between heterogeneous processors, ultimately improving processing performance and real-time response capabilities.
[0103] In step 105, based on the update program, a second executable code for the central processing unit task is generated on the central processing unit, and the first executable code and the second executable code are encapsulated to obtain the compilation result of the program to be processed.
[0104] In some embodiments, based on the update program, a second executable code for the CPU tasks is generated on the CPU. This second executable code refers to a sequence of instructions that the CPU can directly recognize and execute. Its content encompasses the general computing tasks retained in the update program and the newly generated control logic for driving the coprocessors. The process of generating the second executable code essentially translates the update program, written in a high-level language or in an intermediate form, into binary code conforming to the CPU instruction set architecture specification, ensuring that the CPU can process input data and send the correct scheduling instructions to the coprocessors according to a predetermined logical order.
[0105] In some embodiments, the first executable code and the second executable code are encapsulated to obtain the compilation result of the program to be processed. Encapsulation refers to merging the first executable code generated for the coprocessor architecture and the second executable code generated for the central processing unit architecture into a unified logical entity or file object. This process does not change the content of the instruction code, but establishes a relationship between the two, enabling the first executable code to be correctly indexed and accessed by the second executable code. The compilation result refers to the final generated software product containing all the instruction information required by the heterogeneous computing system, which can be directly loaded and executed by the operating system.
[0106] In some embodiments, the generation of the second executable code of the CPU task on the CPU based on the update program can be implemented as follows: based on the CPU task and the control logic included in the update program, a first code representation associated with the CPU architecture is generated; the operation code included in the first code representation is mapped to a plurality of CPU instructions; based on the plurality of CPU instructions, a first instruction sequence including virtual registers is generated; the virtual registers in the first instruction sequence are replaced with physical registers to obtain a second instruction sequence; the second instruction sequence is converted into machine instructions supported by the CPU to obtain the second executable code.
[0107] In some embodiments, generating a first code representation associated with the CPU architecture, based on the CPU tasks and control logic included in the updater, is an intermediate step in the compilation process. The high-level language description in the updater is transformed into a structured form that is closer to the hardware but still maintains a certain degree of abstraction. This first code representation is independent of specific programming languages but closely related to the basic architectural characteristics of the target CPU, such as its supported addressing modes and data types. It provides a unified analytical basis for subsequent instruction selection and optimization. At the low-level implementation, the generation of the first code representation is completed by the compiler's front-end. Through lexical analysis, syntax analysis, and semantic analysis, the source code or intermediate code of the updater is converted into a three-address code or a static single-assignment form. This form clearly expresses each basic operation and the relationship between operands.
[0108] In some embodiments, mapping the operation codes included in the first code representation to multiple CPU instructions, and generating a first instruction sequence including virtual registers based on these CPU instructions, is a process of transforming abstract computation into concrete instruction set operations. The operation codes are the basic arithmetic units in the first code representation, such as addition or loading, while the CPU instructions are instructions that the target CPU hardware can directly recognize. The mapping process selects one or more equivalent instructions from the CPU's instruction set based on the semantics of the operation codes. Virtual registers are theoretically an unlimited number of temporary storage units used to store intermediate results during the instruction selection phase, avoiding premature consideration of the complexity of physical register limitations. At the underlying implementation level, this mapping process typically employs tree pattern matching or graph covering algorithms. The compiler backend traverses the first code representation, identifies patterns that can be efficiently completed by a single or a few CPU instructions, and replaces them with corresponding instruction sequences. The operands in the generated first instruction sequence are all identified using virtual registers.
[0109] In some embodiments, the virtual registers in the first instruction sequence are replaced with physical registers to obtain a second instruction sequence. This second instruction sequence is then converted into machine instructions supported by the CPU to obtain the second executable code. This is the back-end optimization and final code generation stage of the compilation process. This process solves the mapping problem between virtual registers and the limited number of physical registers on the CPU. Its goal is to keep frequently accessed data in high-speed physical registers as much as possible to reduce access to slow memory. When physical registers are insufficient to hold all active virtual registers, some data needs to be temporarily stored in memory, i.e., register overflow. At the low-level implementation level, the replacement of virtual registers with physical registers typically uses a graph coloring algorithm for register allocation. After allocation, the operands in the resulting second instruction sequence are all physical registers or memory addresses. Finally, the assembler translates each instruction in the second instruction sequence into its corresponding binary machine code and integrates them into an executable file format that conforms to the requirements of a specific operating system and hardware platform, thereby obtaining the second executable code.
[0110] Thus, by mapping the operation code in the first code representation to the native instructions of the target CPU and optimizing the allocation of virtual registers to physical registers, a second executable code highly adapted to a specific CPU architecture can be generated. The register allocation process is key to improving performance. By moving frequently used variables and intermediate results from memory to physical registers, the number of memory accesses of the program is greatly reduced. Since the access speed of physical registers is much faster than that of memory, each successful register allocation means that a high-latency memory access is replaced by a low-latency register access. This optimization reduces the pause cycles of the CPU due to waiting for data, thereby directly improving the execution speed of the second executable code. This allows the CPU task itself and the control logic used to drive the coprocessor to run more efficiently, shortening the overall task response time.
[0111] Thus, by acquiring a program containing both CPU and coprocessor tasks, and determining the task interface for task allocation from the program, the first executable code required by the coprocessor can be directly generated based on the logical relationship of the task interface. The original logic in the program that calls the task interface is automatically updated to control logic executed by the CPU. The control logic internalizes the interaction details required to drive the coprocessor to execute the first executable code, thereby reducing the work of manually writing complex logic such as low-level data transmission, task startup, and synchronization. By generating the second executable code for the CPU based on the updated program containing this control logic, and encapsulating the first and second executable codes, an automated conversion from a unified program to the final compiled result is achieved. The integrated compilation process avoids the need to maintain independent code for different processors and manually manage the interaction between processors, significantly reducing development workload and the possibility of introducing errors, thereby effectively improving compilation efficiency.
[0112] The following will describe an exemplary application of the embodiments of this application in a real-world program compilation scenario.
[0113] This application embodiment allows you to directly write a code, using the program compilation method provided in this application embodiment, to separate the code executed by the CPU and the code executed by the coprocessor at compile time. The code executed by the coprocessor is further generated into a hardware format that supports write processing, and then an executable program is formed. At the same time, after compilation, coprocessor control code and code that synchronizes the CPU and the coprocessor will be inserted at the places where CPU and coprocessor synchronization is performed. End users can easily program and run programs.
[0114] In some embodiments, a set of APIs and CPU code are defined and made available for user invocation. Users use this abstract programming method of the API to invoke the CPU and coprocessor to execute tasks and implement certain algorithms. The user-written CPU-side program is compiled using the compilation method of this application, generating executable code for both the CPU and coprocessor, which are then assembled into an executable program. Executing this executable program executes the code transformed during compilation, assigns tasks to the coprocessor after the CPU starts, performs synchronization operations where necessary, and ultimately completes the entire asynchronous execution process.
[0115] In some embodiments, the following steps are mainly performed during compilation: First, the user program is compiled into an intermediate representation, such as LLVMIR. This involves executing a scanning method specified in this compilation method to scan the CPU-executed IR for function calls to the coprocessor. These specific APIs are marked. The call flow graph is extracted and converted into a custom intermediate representation, DSL-IR, representing the computation process as a computation graph. The extracted control flow graph is analyzed and optimized using multiple proprietary traversal algorithms, resulting in the converted DSL-IR representation. A proprietary CodeGen pass is then executed to generate a hardware encoding format sequence recognized by the coprocessor. Next, the binary code for CPU execution is generated in the CPU's IRCodeGen pass. The hardware encoding format sequence generated for the coprocessor is also wrapped in an executable program, and their direct address offset indices are inserted. Finally, an executable program object is completed, containing code that both the CPU and coprocessor need to execute.
[0116] In some embodiments, during program execution, the CPU executes ordinary instructions directly. When it reaches a point where coprocessor instructions need to be executed, it executes coprocessor control instructions inserted during compilation, setting the code offset to be executed by the coprocessor in the coprocessor's registers. When the CPU and coprocessor need to synchronize, the CPU performs the necessary register insertion steps or synchronization waiting steps to complete data exchange with the coprocessor. After synchronization, both continue execution. The CPU continues executing other tasks or the next synchronization task until it receives a signal indicating that the coprocessor has completed execution, until the program terminates.
[0117] In some embodiments, the method for building the control flow graph involves marking the APIs of the coprocessor at definition time, obtaining subgraphs of API calls from the IR execution process, and requiring that the APIs in these subgraphs are executed sequentially without a terminator. For complex entire programs, the program is divided into several independently executable subgraphs according to the above rules, each subgraph having a unique number.
[0118] In some embodiments, the process of rewriting the CPU intermediate representation IR involves deleting nodes from the subgraph in the computation graph, inserting instructions to start the coprocessor at the point of entry into the subgraph, and inserting corresponding transformed nodes after the inserted starting node at points in the subgraph that require synchronization or register settings. The transformed IR contains only code that the CPU can execute.
[0119] In some embodiments, the packaging method after generating CPU and coprocessor binary code involves each subgraph independently executing a DSL-IR compilation process, generating a sequence of DSL-IR instructions. These instructions are then packaged, with the starting offset of each instruction block set as a label, and each label corresponding to an accessible symbol entry. Finally, during linking, the labels in the coprocessor startup instructions are replaced with the offset addresses of the DSL-IR instruction blocks.
[0120] In some embodiments, see Figure 6 , Figure 6 This is a schematic diagram illustrating the principle of the compilation method of the program provided in the embodiments of this application. Figure 1 The module labeled as having CPU code in DRAM is connected to the CPU via an arrow, and the CPU is connected to the coprocessor via another arrow, illustrating the flow relationship between CPU code in DRAM, CPU, and coprocessor under this dynamic execution mode.
[0121] In some embodiments, see Figure 7 , Figure 7 This is a schematic diagram illustrating the principle of the compilation method of the program provided in the embodiments of this application. Figure 2 The module labeled as CPU code in DRAM is connected to the CPU via an arrow, the CPU via another arrow is connected to the coprocessor, and the coprocessor via yet another arrow is connected to the coprocessor instructions. This illustrates the execution relationship in static execution mode, starting from the CPU code in DRAM, passing through the CPU and coprocessor, and finally reaching the coprocessor instructions.
[0122] In some embodiments, see Figure 8 , Figure 8 This is a schematic diagram illustrating the principle of the compilation method of the program provided in the embodiments of this application. Figure 3 Starting with compiling the CPU program, the process then scans the APIs related to the coprocessor. This scanning step triggers the generation of a coprocessor computation graph, followed by optimization of the computation graph and code generation. On the other hand, this scanning step also triggers the transformation of the original computation graph and code generation. The results of the two code generation steps are finally merged, and an executable program is generated based on the merged result.
[0123] In some embodiments, see Figure 9 , Figure 9 This is a schematic diagram illustrating the principle of the compilation method of the program provided in the embodiments of this application. Figure 4The device source code is converted into LLVM IR through front-end code generation, and then enters a static processing stage. Finally, the LLVM IR containing coprocessor instructions is generated by back-end code to produce CPU binary instructions. The specific process of static passthrough is further elaborated: First, the original LLVM IR undergoes static checking and block splitting, decomposing it into multiple LLVM IR fragments, one of which is identified as an LLVM IR fragment (static block). Next, this static block is converted into DSL IR and marked as -xxx-api-llvm var. Then, the DSL IR undergoes DSL Passes for DSL IR optimization. Specific optimization steps include DSL-IR transformation (e.g., 1. loop unrolling, 2. instruction rearrangement) and DSL IR optimization (e.g., 1. built-in function unrolling, 2. register allocation, 3. common subexpression elimination). The optimized DSL IR then performs instruction generation, producing coprocessor instructions. These instructions include operations such as storing variables into registers, -xxx built-in functions, -xxx built-in functions, and loading variables from registers. These coprocessor instructions trigger LLVM IR rewriting, generating new LLVM IR fragments. For example, rewriting "storing variables into registers" into a code snippet of "calling a set register" (e.g., %inst = xxx callxxx_call). (%inst)) rewrites the code snippet "load variable from register" to "call get register"; finally, the rewritten LLVM IR fragment, together with the original LLVM IR fragment, updates the LLVM IR, completing the entire static pass process.
[0124] The following description continues to illustrate the exemplary structure of the program compilation device 455 provided in the embodiments of this application as a software module. In some embodiments, such as Figure 2As shown, the software modules in the program compilation apparatus 455 stored in the memory 450 may include: an acquisition module for acquiring a program to be processed, the program to be processed including a central processing unit task executed by a central processing unit and a coprocessor task executed by a coprocessor; an interface module for determining, from the program to be processed, a task interface for instructing the allocation of the coprocessor task to the coprocessor for execution; a generation module for generating, based on the logical relationship of the task interface in the program to be processed, a first executable code of the coprocessor task on the coprocessor; an update module for updating the original logic in the program to be processed for calling the task interface to control logic executed by the central processing unit, to obtain an update program, the control logic being used by the central processing unit to drive the coprocessor to execute the first executable code; and an encapsulation module for generating, based on the update program, a second executable code of the central processing unit task on the central processing unit, and encapsulating the first executable code and the second executable code to obtain the compilation result of the program to be processed.
[0125] In some embodiments, the interface module described above is configured to perform code conversion on the program to be processed to obtain a first reference code of the program to be processed; identify an instruction sequence executed by the central processing unit from the first reference code, and detect the instruction sequence to obtain a detection result; when the detection result indicates that there is a target call instruction for calling the coprocessor in the instruction sequence, mark the target call instruction as the task interface.
[0126] In some embodiments, the generation module is further configured to parse the calling order of each task interface in the program to be processed, and determine the data dependency relationship between the task interfaces based on the transmission relationship between the input parameters and output parameters of the task interfaces; construct a task graph structure for describing the execution task flow of the coprocessor task based on the calling order and the data dependency relationship; map the nodes in the task graph structure to reference operators, and map the connection relationship between the nodes in the task graph structure to the data index relationship between the reference operators; and generate the first executable code of the coprocessor task on the coprocessor according to the topological order of the task graph structure, based on the data index relationship between the reference operators and the reference operators.
[0127] In some embodiments, the task interface includes a first task interface and a second task interface. The generation module is further configured to obtain the output parameter set of the first task interface and the input parameter set of the second task interface. When the output parameter set of the first task interface and the input parameter set of the second task interface have an intersection, the directed edges in the task graph structure pointing from the node corresponding to the first task interface to the node corresponding to the second task interface are determined as the data dependency relationship between the first task interface and the second task interface.
[0128] In some embodiments, the generation module is further configured to update the reference operators based on the data index relationship between the reference operators to obtain the target operators; perform static memory planning on the data objects associated with the data index relationship between the target operators to obtain the physical storage address of the data objects in the coprocessor memory; convert the target operators into machine instructions supported by the coprocessor, and write the physical storage address into the operand field of the machine instructions to obtain the first executable code.
[0129] In some embodiments, the generation module is further configured to determine the lifecycle and required memory size of each data object according to the topological order of the target operator; determine the memory offset of each data object based on the lifecycle and memory size of the data object, the memory offset being used to indicate the starting position of the data object in the coprocessor memory; and determine the physical storage address of the data object in the coprocessor memory according to the preset base address of the coprocessor memory and the memory offset of each data object.
[0130] In some embodiments, the update module is further configured to identify a sequence of arithmetic instructions for executing the function of the task interface from the program to be processed, and determine the sequence of arithmetic instructions as the original logic; construct an interactive instruction sequence for driving the coprocessor to execute the first executable code based on the calling specification of the first executable code, and determine the interactive instruction sequence as the control logic; replace the original logic in the program to be processed with the control logic to obtain the updated program.
[0131] In some embodiments, the update module is further configured to: construct a data preparation instruction based on the input parameter passing mechanism defined in the calling specification of the first executable code, wherein the data preparation instruction instructs the CPU to transfer the input data required for executing the coprocessor task from the CPU storage space to the coprocessor storage space; construct a task startup instruction based on the task startup protocol defined in the calling specification of the first executable code, wherein the task startup instruction instructs the CPU to write the entry address of the first executable code on the coprocessor into a designated control register of the coprocessor to trigger the coprocessor to start execution; construct an execution synchronization instruction based on the task completion and result return protocol defined in the calling specification of the first executable code, wherein the execution synchronization instruction instructs the CPU to poll the status register of the coprocessor to retrieve the output data of the coprocessor task from the coprocessor storage space after knowing that the coprocessor has completed execution; and construct the data preparation instruction, the task startup instruction, and the execution synchronization instruction into the interactive instruction sequence.
[0132] In some embodiments, the above-described encapsulation module is further configured to: generate a first code representation associated with the central processing unit architecture based on the central processing unit task and the control logic included in the update program; map the operation code included in the first code representation to a plurality of central processing unit instructions; generate a first instruction sequence including virtual registers based on the plurality of central processing unit instructions; replace the virtual registers in the first instruction sequence with physical registers to obtain a second instruction sequence; and convert the second instruction sequence into machine instructions supported by the central processing unit to obtain the second executable code.
[0133] This application provides a computer program product, which includes a computer program or computer-executable instructions stored in a computer-readable storage medium. An electronic device's processor reads the computer-executable instructions or computer program from the computer-readable storage medium and executes the computer-executable instructions or computer program, causing the electronic device to perform the program compilation method described above in this application.
[0134] This application provides a computer-readable storage medium storing computer-executable instructions or a computer program. When the computer-executable instructions or the computer program are executed by a processor, the processor will execute the compilation method of the program provided in this application. For example, ... Figure 3 The compilation method of the program is shown.
[0135] In some embodiments, the computer-readable storage medium may be a memory such as FRAM, ROM, PROM, EPROM, EEPROM, flash memory, magnetic surface memory, optical disk, or CD-ROM; or it may be a variety of electronic devices including one or any combination of the above-mentioned memories.
[0136] In some embodiments, computer-executable instructions or computer programs may take the form of programs, software, software modules, scripts, or code, written in any form of programming language (including compiled or interpreted languages, or declarative or procedural languages), and may be deployed in any form, including as stand-alone programs or as modules, components, subroutines, or other units suitable for use in a computing environment.
[0137] As an example, a computer executable instruction or computer program may, but does not necessarily, correspond to a file in a file system. It may be stored as part of a file that holds other programs or data, for example, in one or more scripts in a Hyper Text Markup Language (HTML) document, in a single file dedicated to the program in question, or in multiple collaborating files (e.g., a file that stores one or more modules, subroutines, or code sections).
[0138] As an example, computer-executable instructions or computer programs may be deployed to execute on one electronic device, or on multiple electronic devices located at one location, or on multiple electronic devices distributed across multiple locations and interconnected by a communication network.
[0139] In summary, the embodiments of this application have the following beneficial effects: (1) By acquiring the program to be processed containing central processing unit (CPU) tasks and coprocessor tasks, and determining the task interface for task allocation from the program to be processed, the first executable code required by the coprocessor can be directly generated based on the logical relationship of the task interface. The original logic of calling the task interface in the program to be processed is automatically updated to the control logic executed by the CPU. The control logic internalizes the interaction details required to drive the coprocessor to execute the first executable code, thereby reducing the work of manually writing complex logic such as low-level data transmission, task startup and synchronization. By generating the second executable code of the CPU based on the update program containing the control logic, and encapsulating the first executable code and the second executable code, the automatic conversion from a unified program to the final compilation result is realized. The integrated compilation process avoids the need to maintain independent code for different processors and manually manage the interaction between processors, significantly reducing the development workload and the possibility of introducing errors, thereby effectively improving the compilation efficiency.
[0140] (2) Since the first reference code with unified semantics is generated through code conversion, the parsing difficulty caused by directly processing heterogeneous source code is avoided, and the stability of the identification process is improved. By performing fine-grained detection on the instruction sequence and marking the task interface, computationally intensive tasks can be separated from the complex control flow. The derivation logic of this process is to transform the heterogeneous programming mode that originally needed to be manually split into an interface marking mode that is automatically perceived by the compiler, reducing the risk of errors caused by human intervention. Finally, through the guidance of the task interface, the coprocessor can efficiently undertake specific operations, reduce the instruction issuance burden of the central processing unit, and thus improve the overall execution efficiency of the program on heterogeneous hardware.
[0141] (3) By extracting parameter sets and determining their intersections to identify data dependencies, the accuracy and automation of heterogeneous program compilation can be significantly improved. Because a criterion based on the intersection of parameter sets is used, the true production-consumption relationships between task interfaces can be accurately identified, avoiding the limitation of parallelism caused by false dependencies. By establishing directed edges in the task graph structure, hidden data dependencies are transformed into intuitive topological constraints. The resulting technical effect is that the compiler can generate first executable code that strictly conforms to sequential logic, ensuring that the coprocessor does not experience data read / write conflicts when performing large-scale parallel computing. This definite dependency provides a basis for the reuse of memory resources, reduces redundant data copying overhead, and thus maximizes the computational performance of heterogeneous systems while ensuring logical correctness.
[0142] (4) By performing static memory planning on data objects during the compilation phase, the physical storage addresses of all data objects in the coprocessor memory are predetermined. This avoids the need for dynamic memory allocation during program execution, thereby eliminating the system overhead of runtime memory management and the uncertainty of execution time. These pre-calculated physical storage addresses are directly written into the operand field of the machine instruction, enabling the coprocessor to skip the intermediate steps of address lookup and translation when executing the first executable code, and directly obtain data through a single memory access operation. This direct address access method reduces the processor's waiting cycle and lowers memory access latency because the coprocessor does not need to interact with the operating system or memory management unit. Therefore, when the final generated first executable code is executed on the coprocessor, the data access efficiency is significantly improved, thereby improving the overall computational performance of the coprocessor task and enhancing the real-time performance and determinism of task execution.
[0143] (5) The precise storage location of data on the coprocessor is determined during the compilation phase. By combining lifetime and memory size analysis, the determination of memory offsets fully considers time reusability, effectively reducing peak memory usage during coprocessor task execution. The physical storage address is obtained through calculation of the base address and offset, eliminating the time overhead and uncertainty caused by runtime dynamic memory allocation. This technical derivation shows that static planning can avoid memory fragmentation problems, and because the address is known, the hardware can directly access data through the physical address without the need for complex memory management units, thus significantly improving the bandwidth utilization and overall computational efficiency of the coprocessor when reading data.
[0144] (6) By parsing the task interface call order and data dependencies in the program to be processed, and constructing a task graph structure, the originally complex and intertwined coprocessor tasks can be clearly logically divided and structurally represented. This structured representation makes the subsequent process of mapping task graph nodes to reference operators and generating the first executable code more efficient and accurate. The clear data dependencies and call order ensure that the generated first executable code of the coprocessor task can correctly handle data flow during execution, avoiding pauses or errors caused by data incompleteness. At the same time, mapping the nodes in the task graph structure to reference operators on the coprocessor makes full use of the characteristics of the coprocessor hardware acceleration unit, enabling each coprocessor task to be executed in its most efficient way. The first executable code generated according to the topological order can maximize the parallel computing capability of the coprocessor, reduce task switching overhead, thereby significantly improving the overall running performance of the program to be processed on the heterogeneous computing platform, reducing power consumption, and shortening the task completion time.
[0145] (7) The original logic typically contains complex and time-consuming computational instructions, while the control logic contains only a small number of configuration and startup instructions. The number of instructions and the execution cycle are much smaller than the threshold. Therefore, when the updated program runs, the CPU utilization rate drops significantly, allowing more time slices to be allocated to operating system scheduling or user interaction tasks. At the same time, this mechanism enables the general-purpose processor and the dedicated coprocessor to form a parallel pipeline, avoiding CPU blocking caused by executing long-time tasks, thereby greatly improving throughput and energy efficiency.
[0146] (8) By solidifying low-level hardware interaction operations such as data preparation, task initiation, and execution synchronization into a set of deterministic interactive instruction sequences, replacing the original high-level abstract call logic, this approach avoids relying on general operating system schedulers or complex driver interfaces for task dispatch during program runtime. General runtime systems typically introduce overheads such as context switching, interrupt handling, and dynamic resource allocation, which can increase the latency of task scheduling and make the timing uncertain. The constructed interactive instruction sequence is optimized for specific hardware and specific tasks. It directly operates on hardware registers, bypassing these high-overhead software layers, thereby greatly shortening the time delay between the central processing unit initiating a task and the coprocessor starting execution, reducing the interaction cost between heterogeneous processors, and ultimately improving processing performance and real-time response capabilities.
[0147] (9) By mapping the operation code in the first code representation to the native instructions of the target CPU and optimizing the allocation of virtual registers to physical registers, a second executable code highly adapted to a specific CPU architecture can be generated. The register allocation process is the key to improving performance. By moving frequently used variables and intermediate results from memory to physical registers, the number of memory accesses of the program is greatly reduced. Since the access speed of physical registers is much greater than that of memory, each successful register allocation means that a high-latency memory access is replaced by a low-latency register access. This optimization reduces the pause cycle of the CPU due to waiting for data, thereby directly improving the execution speed of the second executable code. This allows the CPU task itself and the control logic used to drive the coprocessor to run more efficiently, shortening the overall task response time.
[0148] The above description is merely an embodiment of this application and is not intended to limit the scope of protection of this application. Any modifications, equivalent substitutions, and improvements made within the spirit and scope of this application are included within the scope of protection of this application.
Claims
1. A method for compiling a program, characterized in that, The method includes: Obtain a program to be processed, which includes a central processing unit task executed by the central processing unit and a coprocessor task executed by the coprocessor. From the program to be processed, determine the task interface used to instruct the coprocessor task to be assigned to the coprocessor for execution; Based on the logical relationship of the task interface in the program to be processed, the first executable code of the coprocessor task on the coprocessor is generated. The original logic in the program to be processed used to call the task interface is updated to control logic executed by the central processing unit to obtain an updated program. The control logic is used by the central processing unit to drive the coprocessor to execute the first executable code. Based on the update program, a second executable code for the central processing unit task is generated on the central processing unit, and the first executable code and the second executable code are encapsulated to obtain the compilation result of the program to be processed.
2. The method according to claim 1, characterized in that, The step of determining, from the pending program, a task interface for instructing the allocation of the coprocessor task to the coprocessor for execution includes: The program to be processed is converted into code to obtain the first reference code of the program to be processed; From the first reference code, the instruction sequence executed by the central processing unit is identified, and the instruction sequence is detected to obtain the detection result; When the detection result indicates that there is a target call instruction in the instruction sequence for calling the coprocessor, the target call instruction is marked as the task interface.
3. The method according to claim 1, characterized in that, The logical relationships include calling order and data dependencies. Generating the first executable code of the coprocessor task on the coprocessor based on the logical relationships of the task interface within the program to be processed includes: The calling order of each task interface in the program to be processed is analyzed, and the data dependency relationship between the task interfaces is determined according to the transmission relationship between the input parameters and output parameters of the task interfaces; Based on the calling order and the data dependencies, a task graph structure is constructed to describe the execution task flow of the coprocessor task; The nodes in the task graph structure are mapped to reference operators, and the connection relationships between the nodes in the task graph structure are mapped to the data index relationships between the reference operators. Based on the topological order of the task graph structure, and the data index relationship between the reference operators, the first executable code of the coprocessor task on the coprocessor is generated.
4. The method according to claim 3, characterized in that, The task interface includes a first task interface and a second task interface. Determining the data dependency relationship between the task interfaces based on the transmission relationship between the input parameters and output parameters of the task interfaces includes: Obtain the set of output parameters of the first task interface and the set of input parameters of the second task interface; When the set of output parameters of the first task interface intersects with the set of input parameters of the second task interface, the directed edges in the task graph structure pointing from the node corresponding to the first task interface to the node corresponding to the second task interface are determined as the data dependency relationship between the first task interface and the second task interface.
5. The method according to claim 3, characterized in that, The step of generating the first executable code of the coprocessor task on the coprocessor according to the topological order of the task graph structure, based on the data index relationship between the reference operators and the reference operators, includes: Based on the data index relationship between the reference operators, the reference operators are updated to obtain the target operator; Static memory planning is performed on the data objects associated with the data index relationship between the target operators to obtain the physical storage address of the data objects in the coprocessor memory; The target operator is converted into machine instructions supported by the coprocessor, and the physical storage address is written into the operand field of the machine instructions to obtain the first executable code.
6. The method according to claim 5, characterized in that, The step of performing static memory planning on the data objects associated with the data index relationships between the target operators to obtain the physical storage address of the data objects in the coprocessor memory includes: The lifecycle and required memory size of each data object are determined according to the topological order of the target operators; Based on the lifecycle and memory size of the data object, a memory offset is determined for each data object, the memory offset being used to indicate the starting position of the data object in the coprocessor memory; The physical storage address of the data object in the coprocessor memory is determined based on the preset base address of the coprocessor memory and the memory offset of each data object.
7. The method according to claim 1, characterized in that, The step of updating the original logic in the program to be processed that calls the task interface to the control logic executed by the central processing unit, to obtain an updated program, includes: Identify the sequence of operation instructions from the program to be processed, which is used to execute the function of the task interface, and determine the sequence of operation instructions as the original logic; Based on the calling specification of the first executable code, an interactive instruction sequence for driving the coprocessor to execute the first executable code is constructed, and the interactive instruction sequence is determined as the control logic; The original logic in the program to be processed is replaced with the control logic to obtain the updated program.
8. The method according to claim 7, characterized in that, The step of constructing an interactive instruction sequence for driving the coprocessor to execute the first executable code, based on the calling specification of the first executable code, includes: Based on the input parameter passing mechanism defined in the calling specification of the first executable code, a data preparation instruction is constructed. The data preparation instruction is used to instruct the central processing unit to transfer the input data required to execute the coprocessor task from the central processing unit storage space to the coprocessor storage space. Based on the task startup protocol defined in the calling specification of the first executable code, a task startup instruction is constructed. The task startup instruction is used to instruct the central processing unit to write the entry address of the first executable code on the coprocessor into a designated control register of the coprocessor to trigger the coprocessor to start execution. Based on the task completion and result return protocol defined in the calling specification of the first execution code, an execution synchronization instruction is constructed. The execution synchronization instruction is used to instruct the central processing unit to poll the status register of the coprocessor so as to retrieve the output data of the coprocessor task from the coprocessor's memory space after knowing that the coprocessor has completed execution. The data preparation instruction, the task start instruction, and the execution synchronization instruction are combined to form the interactive instruction sequence.
9. The method according to claim 1, characterized in that, The step of generating the second executable code for the central processing unit task on the central processing unit based on the update procedure includes: Based on the central processing unit tasks and control logic included in the update procedure, a first code representation associated with the central processing unit architecture is generated; The operation code included in the first code representation is mapped to multiple central processing unit instructions, and a first instruction sequence including virtual registers is generated based on the multiple central processing unit instructions; The virtual registers in the first instruction sequence are replaced with physical registers to obtain the second instruction sequence; The second instruction sequence is converted into machine instructions supported by the central processing unit to obtain the second executable code.
10. A program compilation apparatus, characterized in that, The device includes: An acquisition module is used to acquire a program to be processed, the program to be processed including a central processing unit task executed by the central processing unit and a coprocessor task executed by the coprocessor. An interface module is used to determine from the program to be processed a task interface for instructing the allocation of the coprocessor task to the coprocessor for execution; A generation module is used to generate the first executable code of the coprocessor task on the coprocessor based on the logical relationship of the task interface in the program to be processed; An update module is used to update the original logic in the program to be processed that calls the task interface to the control logic executed by the central processing unit, thereby obtaining an updated program. The control logic is used by the central processing unit to drive the coprocessor to execute the first executable code. An encapsulation module is used to generate a second executable code for the central processing unit task on the central processing unit based on the update program, and to encapsulate the first executable code and the second executable code to obtain the compilation result of the program to be processed.
11. An electronic device, characterized in that, The electronic device includes: Memory is used to store executable instructions or computer programs. A processor, configured to execute computer-executable instructions or computer programs stored in the memory, implements the compilation method of the program according to any one of claims 1 to 9.
12. A computer-readable storage medium storing computer-executable instructions or a computer program, characterized in that, When the computer-executable instructions or computer program are executed by a processor, they implement the compilation method of the program according to any one of claims 1 to 9.
13. A computer program product, comprising a computer program or computer-executable instructions, characterized in that, When the computer program or computer-executable instructions are executed by a processor, they implement the compilation method of the program according to any one of claims 1 to 9.
Citation Information
Patent Citations
Hardware acceleration method, compiler, and device
CN106325967A
Code compiling method and device, electronic equipment, storage medium and heterogeneous system
CN113031954A
Method and device for improving execution performance of source program and computer storage medium
CN113553061A
Memory management method, storage medium and electronic equipment
CN120909952A
Prefetch for systems with heterogeneous architectures
US20100153934A1