Semi-automatic function vectorization compilation optimization method for user-defined complex function

By adding compiler directives at loop structures and using the compiler to generate vectorized function declarations, the problem of complex functions being difficult to vectorize is solved, achieving efficient compilation optimization and resource conservation, making it suitable for modern high-performance computing environments.

CN121300798APending Publication Date: 2026-01-09Chinese People's Liberation Army Cyberspace Force Information Engineering University
View PDF 0 Cites 0 Cited by

Patent Information

Application Number
CN202511385168.3
Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
Filing Date
2025-09-26
Publication Date
2026-01-09

AI Technical Summary

Technical Problem

Existing function vectorization methods struggle to handle complex functions, especially custom complex functions, leading to low compilation efficiency and excessive resource consumption.

Method used

A semi-automatic function vectorization compilation optimization method for user-defined complex functions is adopted. By adding compilation directives at loop structures, the compiler generates vectorized function declarations and calls manually vectorized versions from pre-compiled static libraries. Combined with the collaborative optimization of the compiler's front-end, middle-end, and back-end, the target code is generated.

Benefits of technology

It significantly reduces compilation time and resource consumption, improves compilation efficiency, enhances developers' control and flexibility over the compilation process, and is suitable for complex function optimization in modern high-performance computing environments.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN121300798A_ABST
    Figure CN121300798A_ABST
Patent Text Reader

Abstract

The invention relates to the technical field of computers, and provides a semi-automatic function vectorization compilation optimization method for a user-defined complex function. The method comprises the following steps: adding a compiling indication statement at a loop structure containing custom complex function calling for marking; a compiler identifies the compiling indication statement to generate a vectorization function statement for the user-defined complex function, calls a manual vectorization version of the user-defined complex function from a pre-compiling static library, and generates a target code; wherein the function declaration is used for declaring that the function has a manual vectorized version provided by a user. By avoiding the process of automatically generating the vectorized version by the compiler, the resource consumption in the compiling stage is effectively reduced, and the overall compiling efficiency is further improved.
Need to check novelty before this filing date? Find Prior Art

Description

TECHNICAL FIELD

[0001] The present application relates to the technical field of computer, and particularly relates to a semi-automatic function vectorization compilation optimization method for user-defined complex functions. BACKGROUND

[0002] Currently, when a loop in a program contains a function call, two compilation optimization methods are usually considered: inlining and function vectorization. Inlining is a compiler optimization technique that directly inserts the function body at the function call site instead of jumping to the function code for execution. Although inlining reduces the overhead of function calls, such as stack pushing, jumping, etc., the effect is particularly obvious when the function is called frequently inside a loop. However, the inlined function body cannot be too large, otherwise it will cause code bloating and affect cache efficiency. In addition, inlining changes the original loop code structure, reducing code readability and usability. Function vectorization is to use SIMD instruction sets to parallel process data, and convert the calculation operations in the loop into instruction sequences that can process multiple data elements simultaneously. It can take advantage of hardware parallelism to speed up the execution speed of the loop, especially for loops involving numerical calculations.

[0003] Currently, function vectorization mainly relies on OpenMP directives for implementation. In this method, to implement function vectorization, OpenMP directives need to be added to both the loop that calls the function and the called function. In OpenMP, #pragma omp declare simd and #pragma omp simd instructions are used to implement directive-based function vectorization. First, the #pragma omp declare simd instruction informs the compiler that the function can be safely SIMD vectorized. When the compiler encounters this instruction, it will try to generate a vectorized version of the function to make more efficient use of the SIMD instruction set when the function is called in the parallel region. Second, by adding the #pragma omp simd directive to the loop containing the function call, when the function call is encountered, the compiler will look for a vectorized version of the function to call. Thus, function vectorization is achieved. In this way, the compiler can make more efficient use of the SIMD instruction set during parallel execution, thereby improving computational efficiency. However, for complex functions (such as those with complex control flow), especially for user-defined complex functions, it is still difficult to fully vectorize them.

[0004] The current function vectorization method based on guide statements requires adding guide statements to the calling point and the called function in the loop to realize vectorization. This method is more cumbersome and increases the burden of programmers. In addition, the existing function vectorization technology has defects in processing complex functions, especially for custom complex functions. These functions are often difficult to vectorize due to their complex control flow and other characteristics, so it is difficult to generate their vectorized versions. SUMMARY

[0005] In view of the problem that the custom complex function is difficult to vectorize in the existing function vectorization method, the present application provides a semi-automatic function vectorization compilation optimization method for user-defined complex functions.

[0006] The semi-automatic function vectorization compilation optimization method for user-defined complex functions provided by the present application comprises: Adding a compilation instruction statement to mark the loop structure containing the custom complex function call; The compiler generates a vectorized function declaration for the custom complex function according to the compilation instruction statement, calls the hand-optimized version of the custom complex function from the pre-compiled static library, and generates target code. The function declaration is used to declare that the function has a hand-optimized version provided by the user.

[0007] Further, the compilation instruction statement guides the compiler to convert the operations in the loop body into single instruction multiple data stream instructions for parallel processing through explicit instructions.

[0008] Further, the compiler generates a function declaration for the custom complex function, and simultaneously calls the hand-optimized version of the custom complex function from the pre-compiled static library to generate target code, specifically comprising: The compiler front end recognizes the compilation instruction statement; The compiler middle end generates a vectorized function declaration and calls the hand-optimized version of the custom complex function for loop vectorization; The compiler back end generates target code.

[0009] Further, the vectorized function declaration is generated through OpenMP SIMD clone optimization; and the hand-optimized version of the custom complex function is called through vectorization optimization.

[0010] Further, the compiler adopts a preset naming specification to name the vectorized custom complex function; the preset naming specification includes a prefix identifier, a vector factor parameter, a branch mask state indicator, and an original function name; the prefix identifier is used to explicitly mark the manual vectorization feature, the vector factor parameter is used to represent the number of SIMD parallel data elements, and the branch mask state indicator is used to represent that the custom complex function is called in conditional / non-conditional branches.

[0011] Further, at the compiler backend, according to the SIMD instruction set characteristics of the target processor structure, binary code binding is performed on the vectorized function declaration generated at the compiler middle end, and function entity association is realized through symbol linking with the precompiled static library. In combination with the microarchitecture characteristics of a specific hardware platform, instruction scheduling optimization and register allocation optimization are performed on the generated machine code, so as to ensure that the final executable file fully adapts to the parallel computing unit of the target platform.

[0012] Further, the precompiled static library is generated through the following process: A custom complex function manual vectorization source file is constructed, the custom complex function manual vectorization source file is compiled into a vectorized object file, and all the vectorized object files are aggregated into a precompiled static library file through a packaging tool.

[0013] Further, the custom complex function manual vectorization source file specifically includes: When the custom complex function manual vectorization source file is constructed, the function naming specification of the manual vectorization version is consistent with the function naming specification in the function declaration generated by the compiler for the custom complex function. When the manual vectorization function code is written, the supported SIMD instruction set of the target platform is explicitly indicated, and corresponding manual vectorization functions are respectively implemented for different vector lengths.

[0014] Further, the custom complex function manual vectorization source file specifically includes: When the custom complex function includes a scalar function, if the data type lengths of variable function parameters are inconsistent, conversion is performed during the transmission of function parameters and return values to maintain the consistency of the data type lengths.

[0015] Further, the custom complex function manual vectorization source file specifically includes: When the custom complex function includes a scalar function, if the parameters of the scalar function are all the same in all parallel iterations or change by a fixed step in each iteration, the parameters of the scalar function are kept as scalar types during the precompilation of the scalar function. When the parameter type in the self-defined complex function is a pointer type, the array element acquisition only accesses the first passed-in address.

[0016] The beneficial effects of the present application are: The present application has the advantages that it realizes semi-automatic function-level vectorization by proposing a new handsimd compilation instruction clause, breaks through the limitations of traditional automatic vectorization methods, and can effectively reduce compilation resource consumption and improve compilation efficiency, especially when facing complex functions. By explicitly declaring the vectorized version with manual optimization, developers can avoid the process of automatically generating the vectorized version by the compiler, thereby significantly reducing the compilation time and resource occupation. In addition, the synergy mechanism of manual optimization and automatic optimization makes the vectorization processing of complex functions no longer rely on completely automatic compiler generation, but turn to the strategy of manual optimization. This semi-automatic vectorization method provides developers with greater flexibility and controllability.

[0017] The technical solutions of the present application also realize optimization in multiple aspects. First, through the structured naming coding rules and cross instruction set architecture management, the compatibility and maintainability of different version functions are guaranteed. Second, in the collaborative optimization framework of the front, middle and back of the compiler, strategies such as SIMD clone linked list and static library binding are adopted, which further improves the efficiency and adaptability in the vectorization process. These innovations effectively improve the performance and applicability of the vectorization technology, especially suitable for the optimization needs of complex functions in modern high-performance computing environments. BRIEF DESCRIPTION OF DRAWINGS

[0018] Figure 1 It is a schematic diagram of function vectorization based on OpenMP instruction statement; (a) represents a schematic diagram of a loop containing function call, (b) represents a schematic diagram of a called function; Figure 2 It is a flowchart of a semi-automatic function vectorization compilation optimization method for user-defined complex functions; Figure 3 It is an example diagram of handsimd compilation instruction clause; Figure 4 It is a schematic diagram of the compiler collaborative optimization process based on the handsimd clause; Figure 5 It is a process diagram of the semi-automatic function-level vectorization framework technology implementation; Figure 6 It is a schematic diagram of storing elements in a vector register of the same length for different data types; Figure 7 It is a schematic diagram of the case where the data type length of the scalar function parameter is inconsistent; (a) represents that the return value is a shorter data type, and (b) represents that the return value is a longer data type; Figure 8 This is a diagram illustrating how function parameters are identified by uniform. Figure 9 Scalar and vector versions of functions with pointer-type parameters are illustrated. Detailed Implementation

[0019] To make the objectives, technical solutions, and advantages of this invention clearer, the technical solutions of the embodiments of this invention will be clearly described below with reference to the accompanying drawings. Obviously, the described embodiments are only some, not all, of the embodiments of this invention. All other embodiments obtained by those skilled in the art based on the embodiments of this invention without creative effort are within the scope of protection of this invention.

[0020] Currently, function vectorization primarily relies on the application of OpenMP directives. However, OpenMP-based function vectorization requires adding directives to both the loop containing the call point and the called function to achieve vectorization operations, such as... Figure 1 As shown.

[0021] While simple function vectorization can be achieved using OpenMP directives, relying solely on OpenMP to automatically generate vectorized versions of complex functions is impractical. Therefore, this invention proposes a semi-automatic function-level vectorization method for custom complex functions, such as... Figure 2 As shown, it includes: Step 1: Add compiler directives to mark loop structures containing custom complex function calls; compiler directives instruct the compiler to convert the operations in the loop body into single-instruction multiple-data instructions for parallel processing.

[0022] Specifically, such as Figure 3 As shown, in this embodiment of the invention, the compiler directive statement is the `handsimd` clause. The `handsimd` clause uses a parameterized declaration syntax, where the `complex()` function, as a user-defined complex function, is identified within the parentheses of `#pragma omp simd{}` using the syntax structure `complex(handsimd)`. According to the simplified OpenMP implementation, the `handsimd` clause is automatically embedded in the vectorized attribute of the `complex()` complex function. Its core function is to declare that the function has a user-provided vectorized implementation. This mechanism effectively reduces resource consumption during the compilation phase by bypassing the compiler's automatic generation of a vectorized version, thereby improving overall compilation efficiency.

[0023] Step 2: The compiler identifies the compilation directive statement as a custom complex function to generate a vectorized function declaration, calls the manual vectorized version of the custom complex function from the pre-compiled static library, and generates target code; wherein the function declaration is used to declare that the function has a user-provided manual vectorized implementation version.

[0024] The method is based on the implementation of the compilation directive statement. The new handsimd clause of the compilation directive statement has a specific semantic definition: the clause guides the compiler to implement semi-automatic function-level vectorization through a declarative programming interface. The core semantic function is to explicitly declare that a specific function has a user-provided manual optimization vectorized implementation version.

[0025] Further, the "automatic call point conversion and manual function body optimization" collaborative optimization mechanism based on the compilation directive statement relies on the compiler front-end, middle-end and back-end, as shown in Figure 3 The complete processing flow includes: Adding a compilation directive statement to mark the loop structure containing the custom complex function call; The compiler front-end recognizes the compilation directive statement; The compiler middle-end generates a declaration of the vectorized function and loops to call the manual vectorized version of the custom complex function; The compiler back-end generates target code.

[0026] 1. Front-end processing mechanism When the developer adds a compilation directive statement in the source code, the compiler front-end starts the recognition mechanism for the instruction in the lexical analysis stage. In the syntax analysis layer, the system performs structure verification through the pre-set syntax rule library, and performs semantic compliance verification based on the type deduction system, and finally embeds the semantic features that pass the verification in the form of extended attribute descriptors in the metadata layer of the abstract syntax tree node.

[0027] 2. Middle-end collaborative optimization strategy In the middle-end stage, the compiler uses semi-automatic function-level vectorization technology to optimize complex functions. This process is different from traditional automatic vectorization, and adopts the collaborative optimization paradigm of "automatic call point conversion and manual function body optimization". Specifically, the compiler generates a standard function declaration for the manual vectorized function through the static linking library to ensure that the manual optimized version can be correctly called in the loop vectorization stage, thereby achieving effective vectorization of complex functions.

[0028] (1) Declaration and management of SIMD cloned functions The SIMD clone optimization pass of the middle-end optimization phase assumes dual core functions in the compiler architecture: one is to construct the normalized declaration of the hand vectorized function, and the other is to establish the corresponding SIMD clone function syntax tree node at the intermediate representation layer. The implementation mechanism of the optimization pass includes the following key steps: The first step is to deeply parse the SIMD optimization attribute metadata embedded in the original function declaration by the semantic analysis module, accurately extract the three types of core metadata required for vectorization through the type deduction system: parameter type topology structure, return value type mode and vectorization bit width parameter required by the SIMD instruction set. Based on the extracted metadata set, the code generator will construct the normalized function prototype that meets the constraints of the target architecture SIMD instruction.

[0029] Then, the optimization pass generates a vectorized version declaration that maintains structural isomorphism with the original function control flow graph through syntax tree reconstruction technology. This process needs to ensure the ABI compatibility of the clone function. After the instantiation of the clone function node is completed, the type conversion module will implement the data type vectorization remapping operation, the core mechanism of which is to systematically convert the scalar parameter types in the original function signature into vector types, and to expand the return value type according to the vectorization factor, thereby establishing a complete vectorized function call interface.

[0030] To meet the cross-module optimization requirements, the optimization pass explicitly sets the external linkage attribute for all SIMD clone function declarations. This design strategy ensures that the linker can correctly parse and call the vectorized function instance across compilation units in a distributed compilation environment, thereby guaranteeing the global consistency of vectorization semantics in the multi-module collaborative optimization scenario.

[0031] The normalized function declaration will be organized into a SIMD clone linked list structure, which maintains the multi-version mapping relationship between the original function and each vectorized variant in the form of a doubly linked list. This linked list structure serves as a key metadata carrier, providing decision-making basis for subsequent optimization phases. In the loop vectorization phase, the compiler will select the optimal function variant from the clone linked list for calling. This dynamic selection mechanism effectively solves the vectorization adaptation problem of complex loop structures, significantly improving parallel computing efficiency.

[0032] (2) SIMD clone naming system To address the identifier management problem of hand vectorized functions, the present invention proposes a naming specification system based on hierarchical features. Compared to the traditional automatic vectorization naming scheme based on compilation instructions (which constructs a hash identifier based on multiple parameters such as vectorization parameters, SIMD length, data type features and memory alignment constraints), the present invention ensures uniqueness while enhancing maintainability features.

[0033] The naming modification rule designed by the application comprises four structured elements of prefix identifier, vector factor parameter, branch mask state indicator and original function name. Specifically, (1) the prefix identifier is used for explicitly marking the manual vectorization feature, and in the embodiment of the application, "_Handsimd" is used as the prefix identifier; (2) the vector factor parameter "simdlen" represents the number of SIMD parallel data elements; (3) the branch mask state indicator (mask parameter, wherein "M" represents that the custom complex function is called in a conditional branch, and "N" represents that the function is called in a non-branch); and (4) the original function name is kept as a suffix to maintain semantic relevance. For example, the "_Handsimd8N_foo" identifier generated after the function foo is vectorized, wherein "8" represents that the SIMD vector width is 8 elements, and "N" indicates that the function is called in a non-branch code segment. The naming mechanism ensures the unique identification of the manually vectorized function, and also maintains good readability and consistency.

[0034] 3. Back-end code generation The back-end code generation stage comprises two core tasks: firstly, according to the characteristics of the SIMD instruction set of the target processor architecture, binary code binding is performed on the vectorized function declaration generated by the middle-end of the compiler, and the function entity is associated through symbol linking with a pre-compiled static library; and secondly, in combination with the micro-architecture characteristics of a specific hardware platform, instruction scheduling optimization and register allocation optimization are performed on the generated machine code, so as to ensure that the final executable file can fully adapt to the parallel computing unit of the target platform and realize the maximum utilization of the SIMD instruction set resources.

[0035] On the basis of the above embodiment, the embodiment provides a method for constructing a static library. The semi-automatic function-level vectorization technology provided by the application realizes automatic vectorization of a call point and transfers the vectorization of a function body to a manual optimization link. As shown in Figure 5 As shown in the figure, in the initial stage, a complex function source file (.c format) containing a manually vectorized implementation needs to be constructed, and the source file is compiled by a compiler through an -o option to generate a target file (.o format). This process is aimed at converting the manually optimized vectorized code into a relocatable intermediate form, thereby laying a foundation for subsequent modular integration.

[0036] After the target file is generated, all dependent.o files are aggregated into a static library file (libXXX.a format) by a packaging tool, where XXX represents a user-defined library identifier. In the embodiment of the present application, the packaging tool is ar in the Linux system, which is a command line tool for managing static files, and its main functions include creating a library file, modifying the library content, and extracting a module in the library. As a standard archiving tool in the Linux / Unix system, ar realizes the intensive management of code modules by creating a structured archive file, and the static library will be bound with the main program in the compilation and linking stage.

[0037] At the source code level, the developer needs to mark the loop structure containing the complex function call with a compilation instruction (#pragma omp simd {complex(handsimd)}). This syntax structure has a dual function: it declares the vectorization requirement of the loop structure and specifies that the semi-automatic function-level vectorization technology is used to process the target function that has been manually optimized.

[0038] The compilation optimization stage includes two key processing flows: the omp simd clone (OpenMP SIMD clone) optimization pass is responsible for generating the function declaration of the manually vectorized version, and the vect (vectorization) optimization pass is responsible for generating the vectorized intermediate representation to realize the automatic calling mechanism of the vectorized version function. In the linking process, the storage path of the static library needs to be explicitly declared by the -L parameter, and the -lXXX parameter (XXX needs to be strictly consistent with the library name identifier) is used to complete the static library binding operation. This mechanism ensures that the linker can accurately identify and integrate the manually optimized vectorized function module. The optimization pass refers to a series of independent, modularized stages in the compilation process that analyze and transform the intermediate representation of the program, and their common goal is to systematically improve the execution efficiency or reduce the code size of the program through code restructuring and refinement.

[0039] It should be particularly pointed out that, since the manually vectorized function is bound to a specific instruction set architecture, the target instruction set architecture parameter must be explicitly specified in the compilation stage to maintain the instruction set consistency of the automatically vectorized code and the manually optimized code. Through the above multi-stage collaborative optimization mechanism, the compiler finally generates an executable file that integrates the manually optimized vectorized function. Experimental data show that this scheme can obtain significant execution efficiency improvement compared to the pure automatic vectorization method, and the performance gain mainly comes from the synergistic effect of manual optimization and compiler automatic optimization.

[0040] On the basis of the above embodiment, the present embodiment provides a function body-oriented manual optimization system. The manual optimization system focuses on the deep optimization of the function body and realizes performance breakthrough through the interface with the compiler collaborative mechanism. The system establishes five core optimization criteria: 1. Manual vectorization function naming and coding method When constructing a manual vectorization source file for a complex function, some writing specifications need to be paid attention to in order to ensure the correctness of the compilation and linking. First of all, the naming specification of the manual vectorization function needs to be consistent with the function naming specification in the function declaration generated by the compiler, that is, the modification rule of the function name is prefixed with _Handsimd to identify the function as a manual vectorization function. Followed by the vector length (simdlen) to indicate the data width processed in the vectorization process. Then the modifier of the branch mask (mask), where M represents the function is called in the conditional branch, and N represents the function is not called in the branch. Finally, the name of the original function is attached to the modified string to maintain the uniqueness and identifiability of the function. For example, the generated modified name _Handsimd4M_foo, _Handsimd identifies the function as a manual vectorization function, 4 represents the vector length of 4, M represents the function is called in the branch, and foo is the name of the original function. This naming rule not only ensures the uniqueness of the function name, but also provides clear function semantic information for the compiler and developers, facilitating identification and calling in the vectorization optimization process.

[0041] 2. Cross-platform SIMD instruction set adaptation strategy When writing manual vectorization function code, first of all, the supported SIMD instruction set of the target platform needs to be determined. Different processor architectures support significantly different SIMD instruction sets, such as Intel processors usually support AVX, AVX2 and AVX-512 instruction sets, while ARM processors support NEON and SVE instruction sets. Therefore, when writing manual vectorization code, the appropriate SIMD instruction set needs to be selected for optimization according to the hardware characteristics of the target platform. Secondly, the width of the vector register is one of the key factors affecting the performance of vectorization, which determines the amount of data that can be processed at a time. For example, the AVX2 instruction set supports 256-bit registers, while the AVX-512 instruction set supports 512-bit registers. In the code design process, the width of the register needs to be fully utilized to achieve efficient data parallel processing. Although the compiler may specify the use of the AVX-512 instruction set, due to its downward compatibility, GCC may still use 256-bit or 128-bit registers in the actual code generation process. For example, when generating a vectorized function call, the compiler will preferentially call a 512-bit manual vectorization function, while when processing a tail loop, it may call a 256-bit manual vectorization function to further optimize performance. Therefore, when writing manual vectorization code, manual vectorization functions need to be implemented for different vector lengths (such as 512-bit, 256-bit and 128-bit) to ensure that the code can run correctly in different scenarios.

[0042] 3. Dynamic allocation mechanism of vector registers for mixed data type parameters When there is a scalar function in a user-defined complex function, if the data type lengths of variable function parameters are inconsistent, conversion is performed in the process of passing function parameters and return values to maintain consistency of data type lengths.

[0043] Specifically, if the data type lengths of scalar function parameters are inconsistent, additional processing is needed to ensure data correctness and consistency. As shown in Figure 6 , a 128-bit register can store 4 32-bit integers (int), but can only store 2 64-bit long integers (long int). Therefore, in the process of passing function parameters and return values, the consistency of data must be ensured, otherwise the correctness and execution efficiency of the program may be affected. As shown in Figure 7 , there are mainly two cases of inconsistent data type lengths: The first case is that the parameters contain multiple data types of different lengths, and the return value is a shorter data type. For example, the function int foo(long int a, int b). For this case, the compiler will use the parameter expansion strategy, that is, two vectorized parameters a1 and a2 are generated for the 64-bit parameter a, so as to maintain the vector alignment of the number of parameters. Specifically, the original function is converted into the vectorized form of vector(4) int foo.simdclone(vector(2) long int a1, vector(2) long int a2, vector(4) int b). In this way, in the 128-bit vector register, the long int type parameter will be allocated to two vector registers, and the int type parameter will be stored in four vector registers, thereby ensuring the consistency of data.

[0044] The second case is that the parameters contain two data types of different lengths, and the return value is a longer data type, for example, the function long int foo(long int a, int b). In this case, GCC handles it by returning an array vector to maintain the consistency of the number of data. Specifically, long int foo(long int a, int b) after vectorization will be as follows: vector(2) long int[2] foo.simdclone(vector(2) long int a1, vector(2) long int a2, vector(4) int b). In this case, the return value is wrapped into an array containing two 64-bit long int vectors, ensuring that these data can be correctly stored and operated in the 128-bit vector register.

[0045] In writing the hand-written vectorization code, the developer needs to understand and follow the way GCC handles the data type length inconsistency in the intermediate representation stage, especially in the adjustment of function parameters and the handling of return values. The key to this process is to reasonably arrange the data type and register mapping to avoid data misplacement or calculation errors caused by length inconsistency, so as to realize the correct vectorization call of the function.

[0046] 4. Scalar-vector conversion mechanism of special marked parameters When there is a scalar function in a custom complex function, if the parameters of the scalar function are the same in all parallel iterations or change by a fixed step in each iteration, the parameters of the scalar function are kept as scalar types when the scalar function is pre-compiled.

[0047] Specifically, when the parameters of the scalar function are marked by the linear clause or the uniform clause, special attention needs to be paid to their transmission and processing. Unlike regular parameters, these specially marked parameters will not undergo an automatic scalar-to-vector conversion process during the compilation stage, but will be transmitted in their original scalar form. In order to ensure that the hand-written vectorization function can correctly handle such parameters, it is recommended to keep the function parameters as scalar types when writing these functions. In the function body, according to the specific needs and the semantics of the marked clause, they are appropriately expanded into vector types. This not only ensures the correctness of parameter transmission, but also maximizes the flexibility of compiler optimization. Especially when performing hand-written vectorization, it is crucial to correctly understand and apply the expansion mechanism of linear and uniform parameters.

[0048] As shown in Figure 8 , taking the AlignLo() function as an example, when its second parameter align is marked by the uniform clause, this parameter is still transmitted in scalar form in the hand-written vectorization version. This processing method embodies the core semantics of the uniform parameter: the value remains completely consistent across all SIMD lanes. Similarly, for linear parameters, although scalar values are transmitted, the corresponding linear sequence values need to be generated according to the vector length and lane index within the function.

[0049] This parameter handling strategy has several advantages: First, it maintains the simplicity of the function interface, ensuring that manually vectorized functions and original scalar functions have a consistent calling convention. Second, it allows the compiler to choose the optimal parameter expansion strategy based on the specific context. In manual vectorization, developers need to adopt different expansion strategies depending on the specific tag type of the parameter. For uniform parameters, broadcast instructions (such as _mm_set1_epi32) can be used directly to expand them into vectors. For linear parameters, however, it is necessary to combine channel indices to generate the corresponding sequence values. This parameter passing method ensures that the function can appropriately handle parameters according to their tag semantics, thereby optimizing execution performance.

[0050] 5. Optimization method for address passing of pointer parameters When the parameter type in a custom complex function is pointer type, only the address of the first passed array element is accessed.

[0051] Specifically, when a function parameter involves a pointer type, the memory address of the array is passed. Therefore, when writing manually vectorized functions, this address is needed to access the specific elements in the array. Figure 9 Taking the `LbpEstimate00()` function as an example, its first parameter `src` is a pointer to an array of type `int`. When passing this parameter, what is actually passed is the address of the array, which is usually of type `unsigned long`, inconsistent with the data type length of the second parameter. Therefore, to ensure consistency in the number of parameters, an extra parameter is needed to handle this difference. The GCC compiler has a specific optimization behavior when handling address parameter passing: when an array address is passed to a vectorized function, the compiler automatically generates multiple identical address copies. This design stems from the optimization requirements of the SIMD instruction set for contiguous memory access. In practice, since all copy addresses point to the same memory location, only the first address needs to be retrieved to correctly access the source array. This means that when a `src` parameter is passed to a function, VF identical addresses are actually passed. Therefore, when retrieving array elements, only the first passed address needs to be accessed, thus correctly retrieving the array content pointed to by `src`. This mechanism is particularly important in manual vectorization because understanding the details of address passing is crucial for writing manual vectorized code and ensuring the correctness of data access when dealing with complex pointer passing and address operations.

[0052] It should be pointed out finally that the above embodiments are only used to illustrate the technical solutions of the present application, but not to limit the same; and although the present application has been described in detail with reference to the foregoing embodiments, it should be appreciated by those skilled in the art that the technical solutions recorded in the foregoing embodiments can be modified, or some technical features thereof can be replaced equivalently; and these modifications or replacements do not make the essence of the corresponding technical solutions deviate from the spirit and scope of the technical solutions of the embodiments of the present application.

Claims

1. A semi-automatic function vectorization compilation optimization method for user-defined complex functions, characterized in that, The application relates to a method for generating a hand vectorized version of a custom complex function. A compilation instruction statement is added to mark a loop structure containing a custom complex function call; A compiler identifies the compilation instruction statement to generate a vectorized function declaration for the custom complex function, calls a hand vectorized version of the custom complex function from a precompiled static library, and generates target code. The function declaration is used to declare that the function has a hand vectorized version provided by a user.

2. The semi-automatic function vectorization and compilation optimization method for user-defined complex functions according to claim 1, characterized in that, The compilation instruction statement guides the compiler to convert operations in a loop body into single instruction multiple data stream instructions for parallel processing through explicit instructions.

3. The semi-automatic function vectorization and compilation optimization method for user-defined complex functions according to claim 1, characterized in that, The compiler generates a function declaration for the custom complex function, calls a hand vectorized version of the custom complex function from a precompiled static library, and generates target code, and specifically comprises the following steps: The compiler front end identifies the compilation instruction statement; The compiler middle end generates a vectorized function declaration and calls a hand vectorized version of the custom complex function in a loop; The compiler back end generates target code.

4. The semi-automatic function vectorization and compilation optimization method for user-defined complex functions according to claim 3, characterized in that, The vectorized function declaration is generated through OpenMP SIMD clone optimization passes, and the hand vectorized version of the custom complex function is called through vectorization optimization passes.

5. The semi-automatic function vectorization and compilation optimization method for user-defined complex functions according to claim 3, characterized in that, The compiler uses a preset naming specification to name the vectorized custom complex function; the preset naming specification comprises a prefix identifier, a vector factor parameter, a branch mask state indicator and an original function name. The prefix identifier is used to explicitly mark the hand vectorization feature, the vector factor parameter is used to represent the number of SIMD parallel data elements, and the branch mask state indicator is used to indicate that the custom complex function is called in a conditional / uncertain branch.

6. The semi-automatic function vectorization and compilation optimization method for user-defined complex functions according to claim 3, characterized in that, In the compiler back end, binary code binding is performed on the vectorized function declaration generated by the compiler middle end according to the SIMD instruction set characteristics of the target processor structure, and function entity association is realized through symbol linking with the precompiled static library; In combination with the microarchitecture characteristics of a specific hardware platform, instruction scheduling optimization and register allocation optimization are performed on the generated machine code to ensure that the final executable file fully adapts to the parallel computing unit of the target platform.

7. The semi-automatic function vectorization and compilation optimization method for user-defined complex functions according to claim 1, characterized in that, The precompiled static library is generated through the following process: A custom complex function hand vectorized source file is constructed, the custom complex function hand vectorized source file is compiled into a vectorized target file, and all the vectorized target files are aggregated into a precompiled static library file through a packaging tool.

8. The semi-automatic function vectorization and compilation optimization method for user-defined complex functions according to claim 7, characterized in that, The custom complex function hand vectorized source file is constructed, specifically comprising the following steps: When the custom complex function hand vectorized source file is constructed, the function naming specification of the hand vectorized version is consistent with the function naming specification in the function declaration generated by the compiler for the custom complex function; When the hand vectorized function code is written, the supported SIMD instruction set of the target platform is explicitly indicated, and corresponding hand vectorized functions are respectively implemented for different vector lengths.

9. The semi-automatic function vectorization and compilation optimization method for user-defined complex functions according to claim 7, characterized in that, The custom complex function hand vectorized source file is constructed, specifically comprising the following steps: When the custom complex function contains a scalar function, if the data type lengths of variable function parameters are inconsistent, conversion is performed during the transmission of function parameters and return values to maintain consistency of the data type lengths.

10. The semi-automatic function vectorization and compilation optimization method for user-defined complex functions according to claim 7, wherein, The method further includes the following steps: When the custom complex function contains a scalar function, if the parameters of the scalar function are the same in all parallel iterations or change by a fixed step in each iteration, the parameters of the scalar function are kept as scalar types during pre-compilation of the scalar function. When the parameters of the custom complex function are pointer types, only the first transmitted address is accessed to obtain array elements.