High performance code parallelization compiler with loop level parallelization
The automatic parallelization compiler system solves the problem of code parallelization in multi-core processor systems, optimizes memory access and data dependencies, adapts to hardware heterogeneity, and improves system performance and resource utilization efficiency.
Patent Information
- Application Number
- CN202380097553.0
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Filing Date
- 2023-04-24
- Publication Date
- 2026-02-03
AI Technical Summary
Existing technologies struggle to effectively parallelize code in multi-core processor systems, particularly in areas such as processor memory access, data dependency management, and hardware heterogeneity, leading to low parallel processing efficiency.
An automatic parallelization compiler system is adopted, which optimizes the code parallelization process through just-in-time loop parallelization structure and hardware-aware methods, takes into account processor memory access and data dependencies, adapts to hardware heterogeneity, and achieves fine-grained hardware resource utilization.
It improves the parallel processing efficiency of multi-core processor systems, optimizes memory access and data transfer, enhances system throughput and processing power, adapts to hardware heterogeneity, and achieves more efficient utilization of hardware resources.
Smart Images

Figure CN121464428A_ABST
Abstract
Description
Technical Field
[0001] This invention generally relates to multiprocessor systems, particularly multi-core systems and parallel computing systems that allow multiprocessing, wherein two or more processors or cores work together to execute multiple program codes and / or processor instruction sets simultaneously. The multiprocessor system or parallel computing system includes multiple central processing units linked together to enable said multiprocessing or parallel processing to occur. In particular, this invention relates to compiler systems for optimizing computer programs executed by parallel processing systems with multiple processing units. More specifically, the described embodiments relate to systems and methods for the automatic parallelization of code executed in the described multiprocessors. In the field of multiprocessor systems, important features and classifications arise, among other factors, from: the handling of processor memory access and whether the system processor is of a single type or multiple types in the system architecture. Background Technology
[0002] In recent years, fundamental changes have been observed in computer architecture, impacting every aspect of data processing and operation in every electronic device, from mobile phones to supercomputers. This is due to the introduction of unprecedented massive parallelism into computer architecture, which conflicts with traditional code optimization and parallelization techniques. In particular, it creates technical requirements for parallelizing computer and processor-specific code to achieve true optimization. While the performance of conventional multi-core approaches (2, 4, or even 32 cores) adopted by the computing industry has slowly stabilized, technology is leveraging multi-core technologies (hundreds or even thousands of cores) to improve performance per watt and per chip area. However, fully unlocking the potential of multi-core approaches to ensure continued advancements in computing performance in the future will require fundamental advancements in computer architecture and programming techniques—almost equivalent to reinventing computing itself. New technological trends in the microprocessor industry have a significant impact on the design of next-generation computing systems, especially on the design of so-called high-performance computing (HPC) systems, with the realization of petaflop-scale operations. The need to shift system concurrency to a geometric growth path necessitates a rethinking of interconnect design, memory balancing, and I / O system design. This will have a significant impact on the design of future HPC applications and algorithms, particularly their parallelization and architecture-specific adaptation. The refactoring required for existing application code may be as significant and technically challenging as the migration from vector HPC systems to massively parallel processors (MPPs) in the 1990s. This comprehensive code refactoring took nearly a decade, thus raising serious concerns about yet another major shift in the existing software infrastructure.
[0003] One of the technical challenges and difficulties also stems from the sudden interrelationships of various technical fields (such as circuit design, computer architecture, embedded hardware / software, programming languages, compilers, applied mathematics for HPC, etc.) with their impact on the performance optimization of new systems. It also arises from technical goals regarding how current constraints on silicon-level device physics can be considered to further optimize CPU design, system architecture, and programming models for future and current systems. If these technical challenges cannot be overcome with appropriate systems (particularly code optimization and parallelization systems), it even raises the question of whether multi-core (or many-core) or multiprocessor architectures are truly a reasonable response to the potential constraints of future IC designs. This invention allows for addressing the technical requirements for new optimized systems arising from these changes within the context of computer architecture, system architecture, and programming models for future computing systems (e.g., HPC systems).
[0004] Moore's Law states that every 18 months, the number of components integrated onto an integrated circuit can double at a fixed cost, and this law still holds true (and, according to the latest results, may continue until 2023). However, traditional sources of performance improvement, such as instruction-level parallelism (ILP) and clock frequency scaling, have plateaued since 2003. In particular, as measured by SPEC benchmarks, processor performance has improved at an annual rate of 52% since 1975, maintaining a remarkably consistent rate since 1986 (see, for example, JL Hennessy and DA Patterson, "..."). Computer Architecture: A Quantitative Approach (Computer Architecture: A Quantitative Approach), 4th Edition, Morgan Kaufmann, San Francisco, 2006. During this period, as the process geometry scales according to Moore's Law, the active capacitance of the circuit shrinks, so the supply voltage can remain constant or even decrease slightly to allow manufacturers to increase clock speeds. This approach is known as "…". constant electric field"Frequency scaling, the method that has driven the continuous growth of CPU clock frequencies over the past fifteen years, has begun to reach its limits below the 90nm scale of silicon lithography, as static power consumption from leakage current begins to outpace dynamic power consumption from circuit switching. Power density has now become a major constraint on the design of new processing elements and will ultimately limit future clock frequency growth for microprocessors. The direct result of this power constraint is clock frequency stagnation, reflected in the plateauing of performance growth rates since 2002. In the years that followed, individual processor cores were nearly three times slower than if they had continued to grow at the historical pace of the previous decade. Other methods of improving performance, such as instruction-level parallelism (ILP) and out-of-order instruction processing, also exhibit diminishing returns. After exhausting other known methods for gaining performance improvements from a single processor, mainstream microprocessor lines..." The industry's response was to halt further increases in clock frequency and the number of cores on the chip. Estimates showed that the number of cores per chip has doubled every 18-24 months since then. Therefore, a new type of parallel system and processor-architecture-specific optimized programming structures were needed to stay ahead of the geometrically growing wave of system concurrency that triggered the parallelism tsunami. The stagnation in clock frequency and the industry's relatively immediate reaction to dual-core architectures led to the emergence of alternative computing approaches, such as Field Programmable Gate Arrays (FPGAs), Graphics Processing Units (GPUs), or data-streaming tiled array architectures (such as TRIPS). A major obstacle to adopting this more aggressive hardware architecture approach is that the understanding in this technology field of how to efficiently program such devices for various applications is even less than that of parallel machines composed of multiple CPU cores.
[0005] Today, in order to run programs in parallel on multi-core processors or multi-processor systems, their code must be rewritten to add some OS parallelization primitives (e.g., ...) manually or through tools. pthread (POSIX thread, i.e.) pthreads POSIX threads provide a parallel execution model structure. It allows programs to control multiple different workflows that overlap in time. Each workflow is called a thread, and these workflows can be created and controlled by calling the POSIX Threads API. POSIX threads are defined by the standard POSIX.1c... Thread extension (IEEE Std 1003.1c-1995)Defined API. Even with high-level interfaces such as OpenMP or MPI, parallelization is not straightforward for two reasons: (i) insufficient synchronization in the resulting code leads to non-deterministic computation; and (ii) excessive synchronization results in insufficient parallelism. However, threads often introduce determinism into programs and rely on programming styles to constrain this determinism towards deterministic goals. Instead of manually parallelizing code, engineers can rely on compilers to automate, for example, loop vectorization or loop parallelization. Note that loop-level parallelization is a core aspect and technical challenge in HPC applications because the loop portion incurs significant computational demands. Opportunities to leverage parallelism often arise in applications where data is stored in random access data structures. However, even simple examples often cannot be automatically parallelized by existing compilers. Furthermore, irregular code structures are a second problem. The following section discusses in detail how the system of this invention uses just-in-time loop parallelization to parallelize loops.
[0006] This leads to a third problem with parallelization: the memory organization of the data. In the summation example, the array to be summed is declared as, for example, a global variable. Therefore, while the computation is distributed, it is centralized. Consequently, each thread gets the required array fragment from its own DRAM. Caching can help, but adjacent cores can slow down due to memory contention, and cache miss rates are affected by the array distribution. Furthermore, maintaining cache consistency in programs that update shared data requires complex hardware, which slows down average memory access time. Caching and memory hierarchies, as well as branch predictors, are hardware features that rely on the principle of locality, which is essentially based on the centralization of data (caching) and fetch code (predictor). Parallel locality applies to data when code and data are distributed. The principle of parallel locality states that consumers should be as close as possible to their producers. The system of this invention also allows for optimizing the producer-to-consumer distance for parallelized code, which is another way to quantify the quality of parallelization.
[0007] In existing technologies, various attempts exist to apply dataflow architectures to parallel computing frameworks and automated parallelization systems in different ways. Dataflow architecture is a dataflow-based computer architecture that directly contrasts with traditional von Neumann or control-flow architectures. However, dataflow architectures lack a program counter, where, conceptually, the executableness and execution of instructions are determined solely by the availability of the instruction's input parameters; therefore, the order of instruction execution is unpredictable, i.e., the behavior is indeterminate. Therefore, there is a need to provide inherently deterministic dataflow architectures that enable automated parallelization compilers to manage complex technical tasks, such as processor load balancing, synchronization, and access to shared resources, by considering the underlying system architecture.
[0008] Generally, this can lead to higher throughput when processing code is executed in parallel in a multi-core or multi-processor system. Multi-processor or multi-core systems (for simplicity, processors and cores will be referred to as processors below) require breaking down code into smaller blocks and managing code execution efficiently. For cores or processors to execute in parallel, the data for each core or processor must be independent. Instances of the same code block can execute simultaneously on several processors to improve throughput. Parallel processing efficiency can be reduced if a processor needs data from another process that was previously executing or is currently performing computation, due to latency in data exchange between processor units and / or latency in data exchange between processor units. Generally, when a processor enters a state where program execution is suspended or not in progress and instructions belonging to that program are not fetched from memory or executed (for whatever reason), these states result in processor idle states, impacting parallel processing efficiency. Data dependencies need to be considered when scheduling processors. Efficiently managing multiple processors and data dependencies to achieve higher throughput is challenging. Methods and systems for efficiently managing code blocks in computationally intensive applications are desired. Please note that latency issues also exist in single-processor systems, where latency-oriented processor architectures are used to minimize the problem. These single-processor systems are microarchitectures of microprocessors designed to serve serial computation threads with low latency. Generally, these architectures aim to execute as many instructions belonging to a single serial thread as possible within a given time window, where the time to fully execute a single instruction from the fetch phase to the exit phase can range from a few cycles to, in some cases, even hundreds of cycles. However, these techniques are not automatically applied to the latency issues of (massively)parallel computing systems.
[0009] Therefore, parallel computing systems require efficient parallel coding or programming, where parallel programming becomes the programming paradigm. It includes, on the one hand, methods for dividing a computer program into parts that can be executed concurrently, and on the other hand, methods for synchronizing concurrent code parts. This contrasts with traditional sequential (or serial) programming and coding. Parallel execution of programs can be supported on the hardware side; programming languages are often adapted to this. For example, parallel programming can be explicitly done by having the programmer execute parts of the program in separate processes or threads, or it can be done automatically so that causally independent (parallelizable) sequences of instructions execute side-by-side (i.e., in parallel). If a computer with a multi-core processor or a parallel computer is available as the target platform, the compiler system can automatically perform this parallelization. Some modern CPUs can also recognize this independence (in the program's machine code or microcode) and distribute instructions to different parts of the processor in this way, allowing them to execute simultaneously (out of order). However, once the processes or threads communicate with each other, in this sense, they are no longer concurrent as a whole, because they influence each other; only the individual subprocesses remain concurrent. Conflicts can occur if the execution order of communication points for each process or thread cannot be defined accordingly, especially so-called deadlocks when two processes wait for (or block) each other, or race conditions when two processes overwrite each other's results. In existing technologies, synchronization techniques, such as mutexes, are used to address this problem. While these techniques can prevent race conditions, they do not automatically allow for optimized parallel processing of processes with minimal processor unit latency.
[0010] Microprocessors are based on integrated circuits, which makes it possible to perform arithmetic and logical operations based on two binary values (the simplest 1 / 0). For this to work, the binary values must be available to the processor's computational units. The processor unit needs to obtain two binary values to compute the result of the expression a = b operand c (a = b operand c). The time required to retrieve the data for these operations is called latency. These latencies have a wide range of layers, including registers, L1 cache, memory access, I / O operations or network transfers, and processor configuration (e.g., CPU vs. GPU). Since each component has latency, the total latency of computation is primarily a combination of the hardware components required in modern computing infrastructures to move data from one location to another. In modern architectures, different software layers (e.g., the operating system) also have a significant impact. The difference between the fastest and slowest location where the CPU (or GPU) obtains data can be substantial (on the order of magnitude > 10). 9 (within the range). Figure 1 This illustrates the formation of latency in modern computing infrastructure. For example... Figure 1As shown, parallel computing machines have been developed with different unique architectures. It is worth noting that parallel architectures enhance the conventional concepts of computer architecture through communication architectures. While computer architecture defines key abstractions (such as user system boundaries and hardware / software boundaries) and organizational structure, communication architecture defines basic communication and synchronization operations. It also addresses organizational structure.
[0011] Computer applications are typically written at the top level based on corresponding programming models, i.e., in high-level languages. Various parallel programming models are known, such as (i) shared address space, (ii) message passing, or (iii) data-parallel programming, involving corresponding multiprocessor system architectures. Shared-memory multiprocessors are one such type of parallel machine. Shared-memory multiprocessor systems offer better throughput and support parallel programs over multiple programming workloads. In this case, the computer system allows processors and groups of I / O controllers to access a set of memory modules via a hardware interconnect. Memory capacity is increased by adding memory modules, and I / O capacity is increased by adding devices to the I / O controllers or adding additional I / O controllers. Processing power can be increased by implementing faster processors or adding more processors. Figure 2 As shown, resources are organized around a central memory bus. Through the bus access mechanism, any processor can access any physical address in the system. Since all processors are assumed, or in practice, equidistant from all memory locations, the access time or latency at memory locations is the same for all processors. This is called a symmetric multiprocessor system.
[0012] Message-passing architecture is another type of parallel machine and programming model. It provides communication between processors as explicit I / O operations. Communication is combined at the I / O level rather than at the memory system level. In message-passing architecture, user communication is performed by operating system or library calls that execute lower-level actions, which include the actual communication operations. Therefore, there is a distance between the programming model and the communication operations at the physical hardware level. Sending and receiving are the most common user-level communication operations in message-passing systems. Sending specifies a local data buffer (to be transmitted) and receiving a remote processor. Receiving specifies the sending process and the local data buffer where the transmitted data will be placed. In a send operation, an identifier or tag is appended to the message, and in a receive operation, a matching rule is specified, such as a specific tag from a particular processor or any tag from any processor. The combination of sending and matching receive completes a memory-to-memory copy. Each end specifies its local data address and a pair of synchronization events. While message passing and shared address spaces have traditionally represented two distinct programming models, each with its own paradigms for sharing, synchronization, and communication, the underlying machine architectures have now tended towards a common organization.
[0013] Finally, data-parallel processing is another class of parallel machines and programming models, also known as processor arrays, data-parallel architectures, or single-instruction multiple-data machines. The main characteristic of this programming model is the ability to perform operations in parallel on each element of large, conventional data structures, such as arrays or matrices. Data-parallel programming languages are typically implemented by looking at the local address spaces of a group of processes (one for each processor), forming an explicit global space. Because all processors communicate with each other and all operations have a global view, shared address spaces or message passing can be used. However, developing only the programming model cannot improve the efficiency of a computer, nor can developing only the hardware. Furthermore, the top-level programming model necessarily introduces boundary conditions imposed by the programming model, such as model-specific architecture. Since parallel programs consist of one or more threads operating on data, the underlying parallel programming model defines what data the threads need, what operations can be performed on the required data, and the order in which the operations are performed. Therefore, machine code optimization for multiprocessor systems is limited due to the boundaries of the underlying programming model. Parallel programs must coordinate the activities of their threads to ensure that dependencies between programs are executed.
[0014] like Figure 1 As shown, parallel computing machines have been developed with different unique architectures, each resulting in different latency times within its computing infrastructure. One of the most common multiprocessor systems is the shared-memory multiprocessor system. Essentially, shared-memory multiprocessor systems are known to have three basic architectures: (i) Unified Memory Access (UMA), (ii) Non-Unified Memory Access (NUMA), and (iii) Cache-Only Memory Architecture (COMA). In the UMA architecture (see...) Figure 3 In NUMA multiprocessor architecture, all processors share physical memory. All processors access all memory words at the same time. Each processor may have its own private cache memory. Peripheral devices also follow the same rules. When all processors have equal access to all peripheral devices, the system is called symmetric multiprocessor. When only one or a few processors can access peripheral devices, the system is called asymmetric multiprocessor. In NUMA multiprocessor architecture (see...),... Figure 4 In COMA multiprocessor architecture, access time varies depending on the location of the memory word. Shared memory, physically distributed across all processors, is called local memory. The collection of all local memory addresses forms a global address space, which all processors can access. Finally, COMA multiprocessor architecture (see...) Figure 5COMA is a special case of the NUMA multiprocessor architecture. In COMA multiprocessor architecture, all distributed main memory is converted into cache memory. COMA architecture can also be applied to distributed memory multicomputers. Distributed memory multicomputer systems consist of multiple computers, typically represented as nodes, interconnected via a message-passing network. Each node acts as an autonomous computer with a processor, local memory, and sometimes I / O devices. In this case, all local memory is private and can only be accessed by the local processor; therefore, such machines are also called No Remote Memory Access (NORMA) machines. Other known multiprocessor architectures include, for example, multivector computers and single-instruction multiple-data (SIMD) parallel computers, parallel random-access machines (PRAM), and parallel computers based on very large-scale integration (VLSI) chips, all of which have different multiprocessor architectures and infrastructure characteristics. In short, because different multiprocessor architectures create different latency times in their computing infrastructure, developing programming models alone cannot improve computer efficiency, nor can developing hardware alone do so.
[0015] As mentioned above, if a computer with multi-core processors or a parallel computer is available as the target platform, the compiler system can also automatically perform code parallelization. This automatic parallelization (also known as self-parallelization) refers to converting sequential code into multi-threaded and / or vectorized code so that multiple processors can be used simultaneously, for example, in a shared-memory multiprocessor (SMP) machine. Fully automatic parallelization of sequential programs using existing systems is technically challenging because it requires complex program analysis and because the optimal approach may depend on parameter values unknown at compile time. The programming control structure of primary concern for compiler system automatic parallelization is loops, as a large portion of a program's execution time typically occurs within some form of loop. There are two main approaches to parallelizing loops: pipelining multithreading and loop multithreading. The compiler architecture for automatic parallelization typically includes a parser, analyzer, scheduler, and code generator. The compiler system's parser covers the first processing stage, where, for example, a scanner reads the input source file to identify all static and external usages. Each line in the file is examined according to a predefined pattern to separate it into tokens. These tokens are stored in a file and later used by the syntax engine. The syntax engine examines marker patterns that match predefined rules to identify variables, loops, control statements, functions, and more in the code. In the second phase, the analyzer identifies code segments that can be executed concurrently. The analyzer uses static data provided by the scanner-parser. The analyzer first detects all completely independent functions and marks them as separate tasks. Then, the analyzer identifies which tasks have dependencies. In the third phase, the scheduler lists all tasks and their dependencies in terms of execution and start time. The scheduler generates an optimal schedule based on the number of processors to use or the application's total execution time. In the fourth (and final) phase, the scheduler generates a list of all tasks and details on which cores each task will execute on and its execution duration. The code generator then inserts special structures into the code, which the scheduler reads during execution. These structures indicate on which cores the scheduler will execute a specific task, along with its start and end times.
[0016] If a compiler uses loop multithreading parallelization, it attempts to split each loop so that each iteration can be executed concurrently on a separate processor. During automatic parallelization, the compiler typically performs two rounds of automatic evaluation before actual parallelization to determine two fundamental preconditions for parallelization: (i) in the first round, is it safe to parallelize the loop based on dependency analysis and alias analysis? And (ii) in the second round, is it worthwhile to parallelize the loop based on an estimate (modeling) of the program's workload and the capacity of the parallel system? The compiler's first round performs data dependency analysis on the loop to determine if each iteration of the loop can be executed independently of other iterations. Sometimes data dependencies can be handled, but it may trigger additional overhead in the form of message passing, shared memory synchronization, or some other processor communication method. The second round attempts to justify the parallelization effort by comparing the theoretical execution time of the parallelized code with the sequential execution time of the code. It is important to understand that code does not always benefit from parallel execution. The additional overhead that may be associated with using multiple processors can cannibalize the potential speedup of parallel code.
[0017] If you use a pipelined multithreaded parallelization compiler for automatic parallelization, the compiler will attempt to break down the sequence of operations within a loop into a series of code blocks, so that each code block can be executed concurrently on a separate processor.
[0018] Many parallel problems involve these relatively independent blocks of code, especially in systems that use pipes and filters. For example, when producing a live stream, many different tasks must be executed within a single second.
[0019] Pipeline multithreaded parallelization compilers attempt to assign each of these operations to a different processor, typically arranged in a systolic array, inserting appropriate code to forward the output of one processor to the next. For example, in modern computer systems, one focus is on leveraging the capabilities of GPUs and multi-core systems to compute such independent blocks of code (or independent iterations of loops) at runtime. The accessed memory (whether directly or indirectly) can then be tagged as different iterations of the loop and compared for dependency detection. Using this information, iterations are grouped into multiple levels so that iterations belonging to the same level are independent of each other and can be executed in parallel.
[0020] In the prior art, there are many compilers for automatic parallelization. However, most modern prior art compilers for automatic parallelization rely on using Fortran as the high-level language, i.e., only for Fortran programs, because Fortran's guarantees on aliases are stronger than those of languages such as C. Typical examples of such prior art compilers are (i) the Paradigm compiler, (ii) the Polaris compiler, (iii) the Rice Fortran D compiler, (iv) the SUIF compiler, and (v) the Vienna Fortran compiler. Other disadvantages of automatic parallelization in prior art compilers are that it is often difficult to achieve high levels of code optimization due to the following facts: (a) dependency analysis is difficult for code using indirect addressing, pointers, recursion, or indirect function calls, because such dependencies are hard to detect at compile time; (b) loops often have unknown iteration counts; (c) it is difficult to coordinate access to global resources in terms of memory allocation, I / O, and shared variables; and (d) irregular algorithms using input-dependent indirection interfere with compile-time analysis and optimization.
[0021] A key task of compilers is to attempt to effectively handle latency. Compilation is the process of transcribing human-readable so-called high-level languages (e.g., C, Python, Java, etc.) into assembler / processor code, which then consists only of the instructions available on a given processor. As already discussed, modern applications with massive data or computational demands must be tailored to appropriate infrastructure and introduce many different types of latency—only a portion of which can currently be addressed by existing compiler optimization techniques.
[0022] For each level of complexity (hardware component), solutions are constantly being developed and evolved, ranging from compiler optimization techniques to multithreaded libraries for concurrent data structures to prevent race conditions, to code vectorization, to GPU systems with corresponding programming languages (e.g., OpenCL (Open Computing Language), to frameworks such as TensorFlow to distribute computation among programmers, to big data algorithms such as MapReduce, where MapReduce is a programming technique and an associative implementation for processing and generating large datasets using parallel distributed algorithms on clusters. In the field of high-performance computing, theoretical and mathematically based techniques have been developed and defined for specialized gridding techniques to decompose large matrices into finite difference or element-wise methods. This includes protocols, such as Message Passing Interfaces (MPI) in cluster infrastructures, that support data transfer to different processes over the infrastructure.
[0023] As discussed above, the list of existing optimization techniques is long. But from a systems theory perspective, the problem is more or less the same: how can code (any code) interact most efficiently with latency in complex hardware infrastructures? Compilers work well when using a single CPU. As hardware complexity increases, compilers can no longer truly parallelize code. Parallelization becomes merely a CPU approximation, for example, by introducing microprocessors. The hardware industry for CPUs, GPUs, and their clusters is primarily focused on its specific domain, and developers and researchers are focused on implementing technologies and frameworks, and have so far not ventured into the realm of more general (cross-industry) approaches. Furthermore, the authors Ruggiero, Martino; Guerri, Alessio; Bertozzi, Davide; Milano, Michaela; and Benini, Luca, in their pamphlet, "A Fast and Accurate Technique for Mapping Parallel Applications on Stream-Oriented MPSoC Platforms with Communication Awareness," *International Journal of Parallel Programming*, Vol. 36, No. 1, February 8, disclose an algorithm for partitioning data streams across different processor cores. The authors' model is a simple communication network with a simple additional communication model between processor cores. This does not allow for realistic conclusions regarding the actual communication load caused by partitioning across multiple cores.
[0024] Generally, known processor manufacturers focus on their processors and related hardware components, while other developers (e.g., high-performance computing (HPC) research groups) focus on the use of numerical methods and libraries. Currently, there is no attempt to address the problem of compiler system optimization from a systems theory perspective by accessing the latency dynamics generated by given source code. Source code in the prior art consists only of a series of statements that result in read / write instructions for a given target infrastructure.
[0025] Existing technical literature includes M. Kandemir et al.'s " Slicing Based Code Parallelization for Minimizing Inter-processor Communication (slice-based generation) Code parallelization)The International Conference on Embedded Systems Compilers, Architectures and Synthesis (Situation '09), Grenoble, France, October 11-16, 2009, pp. 87-96, discloses a system for automatic parallelization aimed at minimizing inter-processor communication in distributed memory multi-core architectures by applying the concept of iterative spatial slicing; that is, this prior art system is based on an iterative method. The disclosed system segments the output array by iteratively determining partitions of other arrays in the application code, i.e., by iteratively determining array portions, where information is iteratively obtained from previously sliced array portions. In code parallelization, slicing refers to the process of extracting statements from a program that may affect statements of particular interest, which are slicing criteria (see, for example, J. Krinke, "..."). Advanced slicing of Advanced slices of sequential and concurrent programs " 20th IEEE Software Proceedings of the International Conference on Maintenance, 2004 2004, pp. 464-468). These slicing techniques exhibit similar effects to existing systems that rely on point data / control dependencies (see, for example, JL Hennessy, DAPatterson, “Computer Architecture,” 5th edition: Quantitative Approaches, Morgan Kaufmann Computer Architecture and Design Series, 5th edition, p. 150) and dataflow analysis (see, for example, Gary A. Kildall, “Aunified Approach to Global Program Optimization,” Proceedings of the First ACM SIGACT-SIGPLAN Symposium on Principles of Programming Languages (POPL'73), ACM, New York, 1973, USA, pp. 194-206). Using iterative space slicing, these systems are able to evaluate which iterations of which statements affect the value of a given set of elements in a particular array A. Thus, the system iteratively returns, for example, the set of loop operations to be assigned to processor p from nested loops by a specific set of data elements accessed from array A by processor p. Furthermore, existing technical literature, such as Fonseca A. et al.'s " Automatic Parallelization: Execution Sequential Programs on a Task-Based Parallel Runtime (Automatic Parallelization: Executing sequential processes on a task-based parallel runtime) sequence)The International Journal of Parallel Programming, April 2016, published another system for automatically parallelizing sequential code for use in multi-core architectures. This system discloses the use of data sets and memory layout, followed by examination of dependencies that depend on task parallelism. Therefore, to automatically parallelize a program, the system must analyze the accessed memory to assess potential dependencies between parts of the program. For example, in the Fibonacci sequence... In an example of automatic parallelization of sequencing code, the disclosed system evaluates that the cost of creating new tasks is higher than the cost of performing the method for a low number of inputs. This evaluation is then used as the primary requirement for task placement during automatic generation of parallelized code, where the evaluation is performed by a specific function that depends on a set of seven requirements to find the optimal placement. Finally, the function outputs so-called hard dependencies (which are instructions that can subsequently introduce tasks) and so-called soft dependencies, which give groups of defined tasks that the current task must wait for before execution. Parallelization is complete when all tasks are instantiated with specified placements, where tasks to be executed are marked by waiting for the current task to execute and reading its results. Finally, US2008 / 0263530A1 discloses a system for converting application code into optimized application code or executable code suitable for execution on a computing architecture including at least first and second level data memory units. When scheduling instructions, the principle of locality, also known as referential locality, is used. This relates to the phenomenon of frequent access to the same value or related memory locations. Different types of referential locality need to be distinguished. In temporal locality... In locality, a resource referenced at a certain point in time is subsequently referenced again very quickly. In spatial locality, if a storage location near a storage location has been recently referenced, that storage location is more likely to be referenced again. Programs and systems exhibiting locality exhibit predictable behavior, thus providing code designers with opportunities to improve performance by prefetching, precomputing, and caching code and data for future use. For this data evaluation optimization, the disclosed system accesses locality before layout locality, thereby concentrating accesses as much as possible temporally as possible for repeatedly accessed data when data transfer operations occur, and concentrating accessed data one after another as much as possible spatially. Therefore, in the first process (access locality), partial fixes are made, thus providing a range of options. In the second process (layout locality), an option is selected from a predefined range. An option can be selected based on a cost function. As a variation of the embodiment, the system also addresses the problem of parallel data transfer and memory exploration by focusing on application code sections with data-parallel loops. The transformation structure allows for the resolution of data-level aspects of different levels of memory units (e.g., background memory, foreground memory, registers) and functional units.
[0026] In summary, while parallelization compilers exist, they typically focus on independent levels of parallelism, such as instruction-level parallelism (ILP), data and vector parallelism (e.g., high-performance Fortran and MMX / SSE functional compilers), or thread-level parallelism (TLP), such as compilers that support the OpenMP API or GPU-enabled PGI accelerator compilers. Even more complex architecture-centric approaches (e.g., IBM's Octopiler) still require manual performance tuning; therefore, all software development processes must be manually adapted to new prerequisites. Algorithms need to leverage and express a variety of multi-level parallelism, finer-grained and nested hierarchical memory systems, and software-managed or user-managed data transfers. Furthermore, application design needs to consider scalability across generations of processors and concepts. Comprehensive hardware knowledge is required to achieve optimal throughput for all steps of the application mapping (e.g., in numerical simulations). Complex trade-offs exist between performance, productivity, portability, and implementation flexibility. In the systems and methods of this invention, hardware-aware computing is achieved by providing the optimal combination of schemes, parallel algorithms, and platform-specific implementations for a given source code of the application.
[0027] Furthermore, unfortunately, existing automated parallelization systems and programming methods for multi-core systems (especially heterogeneous parallel systems) are currently unsuitable for the specific needs of such systems: high-level parallel programming models provide an abstract view required by today's complex applications, but lack fine-grained control over hardware mapping, resulting in low hardware resource utilization. Rigorous hardware-aware approaches can achieve this fine-grained control in the long run, but they place a heavy emphasis on hardware mapping. The inventive systems and methods based on hybrid approaches offer a novel combination of two aspects.
[0028] As discussed further below, conventional prior art parallel programming approaches can be categorized into three domains: shared memory, message passing, and data parallelism, each with its own standardized programming environments. Examples include (in the order of the domains) OpenMP (Open Multiprocessing) for compiler-available TPL (Task Parallel Library), MPI (Message Passing Interface) for manually exploitable thread-level and pipelined parallelism, and high-performance Fortran for compiler-supported data parallelism (DP). These programming models offer only marginal flexibility and typically do not support fine-grained architecture mapping. Of these three domains, message passing provides the highest level of control over application architecture mapping. On the downside, it forces programmers to perform detailed partitioning and orchestration. Furthermore, one of the biggest drawbacks is that none of these models typically express hardware heterogeneity, as this is beyond their scope. OpenMP offers some flexibility, allowing dynamic changes to the number of threads to be created. Partitioned Global Address Space (PGAS) is a programming interface that defines the possible global address space on a distributed system, emphasizing reference locality of reference: using PGAs, portions of the shared memory space can have affinity for specific threads. Examples of this model are Unified Parallel C and Co-array Fortran, as well as more recent industry-driven approaches such as Chapel (Cray) and X10 (IBM).
[0029] In particular, heterogeneous platforms require fine-grained matching of application code to a given platform at the lowest hardware level: an example of existing technology is Cell BE, which forces programmers to explicitly divide the program into chunks to be executed on a single vector processing unit (SPE). Communication must be explicitly defined using so-called direct memory access streams, enabling each SPE to fetch the required data and write back the resulting data. This careful matching of computation and communication can deliver orders of magnitude speedup compared to simpler implementations. However, this is a rather tedious, error-prone, and time-consuming task. Conventional homogeneous multi-core platforms also require hardware-aware programming techniques to minimize communication overhead, for example, through data locality optimization and proper prefetching. This is becoming more prevalent with the emergence of current and upcoming multi-core architectures, which employ different cache sharing and interconnection schemes.
[0030] Another problem with all the existing technical approaches discussed is the need for an additional runtime layer and often language-centric extensions. Furthermore, they do not consider the application's needs, such as real-time requirements or computational precision. Another existing technical approach is based on carefully extending an existing system layer. However, it is inherently language-independent and operating system-independent, and incompatible with existing parallel programming models. Moreover, the overhead does only occur in triggered options (such as performance measurement and functional analysis for bootstrapping execution), and the analysis overhead is still about an order of magnitude lower than typically required.
[0031] To achieve true hardware-optimized parallelism, all parts of the application code need to conform to multi-level parallel units, hierarchical and potentially nested memory subsystems, and heterogeneous components of computation units. All aspects need to be explicitly expressed in the implementation: in existing technologies, there is very little software support and few mechanisms to help automate and optimize resource utilization, and to hide hardware details without impacting performance. Despite the increasing heterogeneity of hardware, it still lacks expression in the algorithms and applications used. Current programming techniques primarily rely on micro-pivots, where local parts of the application are identified for acceleration and offloaded to specific computation engines. Additional communication through narrow bottlenecks must be considered for overall benefit. However, existing solutions are often siloed and non-portable. Hardware-specific optimization techniques include computational arrangements (e.g., vectorization, loop unrolling, reordering, branch elimination), data structure optimizations (array access patterns, memory alignment, data merging), and data transfer optimizations (blocking due to spatial and temporal locality, caching and cache bypass, in-situ algorithms). This should include parameter space, as it is becoming increasingly difficult to manage. Using known existing technology systems, it is impossible to bypass the automatic tuner to search for the (Pareto-) optimal settings for implementing parameters. Automatic tuning may provide results for a selected kernel, but the cost is usually a lack of cross-platform portability. Summary of the Invention
[0032] One object of this invention is to provide a compiler system for multiprocessor systems and multicomputer systems that compiles program code into machine code with optimized latency for the processing units of the multiprocessor system, thereby efficiently managing multiple processors and data dependencies to achieve higher throughput, and without the drawbacks of prior art systems discussed above. In particular, an object of this invention is to provide a system and techniques that can be used to achieve maximum performance in multiprocessor machines through automatic parallelization, thereby optimizing the utilization of low-level parallelism (time and space) at the machine instruction processing level. Another object of this invention is to overcome the shortcomings of prior art in handling the limitations of parallelization portions, which are often confined to specific systems, such as loops or specific code segments. Automatic parallelization systems should be able to optimize the identification of parallelization opportunities, a critical step in generating multithreaded applications.
[0033] According to the invention, these objectives are achieved, in particular, by the features of the independent claims. Furthermore, further advantageous embodiments can be derived from the dependent claims and related descriptions.
[0034] According to the present invention, the aforementioned objective of a symmetric automatic compiler system and its corresponding method is achieved. This symmetric automatic compiler system is used for the automatic parallelization of hardware-optimized program code for execution by a multi-core or multi-processor parallel processing system having multiple processing units. These multiple processing units simultaneously process data-related instructions within the parallel processing system by executing the program code. Specifically, the automatic compiler system includes means for converting serial source code written in a programming language into parallel processing machine code. This parallel processing machine code includes multiple instructions executable by the multiple processing units of the parallel processing system or controls the operation of the multiple processing units. The parallel processing system includes a memory unit, which... The system includes at least a main execution memory unit and a transition buffer unit. The main execution memory unit includes multiple memory banks for holding data for at least a portion of the processing code. The transition buffer unit includes high-speed memory for storing the starting location of the processing code and data segments, which at least include branch or jump instructions and / or memory references and data values. The main execution memory unit provides slower access times than the transition buffer unit. The execution of the processing code by the parallel processing system includes latency, which is given by the idle time between the processing unit sending back data after processing a specific instruction block of the processing code and receiving the data required for the processing unit to execute the subsequent instruction blocks of the processing code. The compiler system includes a parser module for converting serial source code into code with a basic instruction stream executable by a processing unit. The basic instructions can be selected from a limited, processing unit-specific set of basic instructions, and the basic instructions only include basic arithmetic and logical operations and / or basic control and store operations for the number of processing units. The parser module includes means for dividing the code of the basic instructions into multiple computational block nodes. Each computational block node consists of the minimum possible segment of an indivisible sequence of basic instructions that can be processed by a single processing unit. The minimum possible segment of the basic instructions is characterized as a sequence of basic instructions consisting of consecutive read and write instructions, which cannot be composed of consecutive... The smaller basic instruction sequences between read and write instructions are further decomposed, and each read and write instruction needs to receive data required by the processing unit to process the basic instruction sequence and return the data after the sequence has been processed. The compiler system includes a matrix builder for generating a matrix from a computation chain segmented by code. This matrix includes a computation matrix, a transport matrix, and a task matrix. Each column in the computation matrix includes a computation block node capable of simultaneous processing based on the executableness of read and write instructions that transmit the data required for processing by the computation block node. The transport matrix contains transport and processing attributes to each computation block node, which at least characterize data transfer attributes from one computation block node to consecutive computation block nodes.The data transfer attributes include at least the data size of the transferred data and the identifiers of the source and target computational block nodes and / or the processing characteristics of one of the multiple processing units, wherein the tasks are formed by a matrix builder, wherein, in the case where the computational block nodes each have different associated reads, the tasks of the task matrix are formed by uniformly dividing the computational block nodes of the columns of the computation matrix into a number of symmetric processing units, forming a task for each of the multiple processing units in each column of the computation matrix, and dividing the remaining computational block nodes into at least a portion of the tasks based on a predefined scheme, and wherein, in the case where the computational block nodes at least partially have reads that have transferred the same data, the tasks are formed by uniformly or substantially uniformly minimizing the number of reads in the number of processing units and / or, if exceeding a predefined offset value, by uniformly minimizing the integrated processing time in each processing unit, and wherein, the compiler system includes a code generator for generating parallel processing machine code with optimized total latency for multiple processing units based on the computational chain given by the optimized task matrix. Furthermore, the compiler system may include, for example, an optimizer module that uses matrix optimization techniques to minimize the total occurrence delay time by providing an optimized structure of tasks within a task matrix, where each column of the task matrix is a computational chain formed by one or more tasks, thereby creating an ordered flow of computational block nodes executed by one of multiple processing units. If matrices or tensors are used, the optimization performed by the optimizer module can, for example, be based on numerical matrix optimization techniques (or more generally, numerical tensor optimization techniques). Technically, the current optimization problem can be determined using tensors and / or matrices, thus obtaining a matrix / tensor field optimization problem. For linear optimization, the optimizer module may, for example, use matrices and linear programming. The concept of tensors may be technically useful for certain applications of the invention. In optimization, tensor techniques are capable of solving nonlinear relationships and systems of equality, and performing unconstrained optimization using second derivatives. Tensor methods can be used as general methods, particularly suitable for problems where the Jacobian matrix is singular or ill-conditioned at the solution. Tensor methods can also be used for linear optimization problems. A key characteristic of tensors is that their values do not change when subjected to conventional nonlinear coordinate transformations. Therefore, this concept can technically be used to characterize structural properties that are independent of conventional nonlinear coordinate transformations. Thus, tensor optimization can also be applied within the framework of nonlinear optimization. However, it must be noted that one of the technical advantages of this invention is that all known matrix optimization methods to date are linear optimization methods, which differs from existing optimization techniques in the field of automatic parallelization of source code, where existing systems primarily rely on nonlinear optimization. In this paper, optimization represents the problem of finding the set of input functions that lead to the evaluation of a maximum or minimum function. For example, for this technically challenging problem,Various machine learning algorithms, from fitting logistic regression models to training artificial neural networks, can be used in conjunction with optimizer modules. If the optimizer module is implemented by an implemented machine learning architecture, it can be formulated, which is typically provided using continuous function optimization, where the input parameters of the function are real-valued numerical values, such as floating-point values. The output of the function is also a real-valued estimate of the input values. However, as a variation of the implementation, optimization functions employing discrete variables can also be used, i.e., providing a combinatorial optimization problem. For example, to technically select the best optimization architecture, one approach could be to group the available optimization architectures based on the amount of information available about the objective function being optimized, which in turn can be used and controlled by the optimization algorithm. Obviously, the more information available about the objective function, the easier it is to optimize that function by machine learning, depending, of course, on whether the available information can be effectively used for optimization. Thus, a selection criterion could be related to a differentiable objective function, for example, by asking whether the first derivative (gradient or slope) of the function can be computed for a given candidate solution. This criterion divides the available machine learning architectures into those that can utilize computed gradient information and those that do not, i.e., those that use derivative information and those that do not. For applications that can use differentiable objective functions, it's important to note that the differentiable function representation in this paper represents a function that can generate a derivative at any given point in the input space. The derivative of a function with respect to a certain value is the rate of change or amount of change of the function at that point, also known as the slope. The first derivative is defined as the slope or rate of change of the objective function at a given point, where the derivative of a function with more than one input variable (e.g., multivariate input) is called the gradient. Therefore, the gradient can be defined as the derivative of a multivariate continuous objective function. The derivative of a multivariate objective function is a vector, and each element in the vector can be called a partial derivative, or the rate of change of a given variable at that point, assuming all other variables remain constant. Furthermore, partial derivatives can be defined as elements of the derivative of a multivariate objective function. The derivative of the derivative of the objective function can then be generated, i.e., the rate of change of the rate of change of the objective function. This is called the second derivative. Therefore, the second derivative can be defined as the rate of change of the derivative of the objective function. For functions with multiple input variables, this is called a Hessian matrix, defined as the second derivative of a function with two or more input variables. Simple differentiable functions can be analytically optimized using known calculus. However, the objective function may not be solvable analytically. If the gradient of the objective function can be generated, the optimization becomes much easier. Some machine learning structures that can utilize gradient information and can be used in this application include: the bracketing algorithm, local descent algorithms, first-order algorithms, and second-order algorithms.
[0035] This invention offers particular advantages by providing and implementing large-scale optimizations based on the lowest possible code structure, simplifying high-level programming language code to a set of basic instructions that cannot be further simplified in terms of their data input and output points due to the limited machine instruction set running on the CPU / microprocessor. For example, the basic instructions include: (i) arithmetic operations in the applied numerical applications: +, -, ... That is, mathematical operations (e.g., integration or differential analysis) are simplified to these basic instructions: (ii) logical operations: AND, OR, etc.; (iii) variable and array declarations; (iv) comparison operations: same, larger, smaller, etc.; (v) code flow: jumps, calls, etc.; (vi) if (condition) {codeA}else{codeB}; and (vii) loops (conditions). The interaction between modern high-level languages (e.g., Python, C, Java, etc.) and limited processor instruction resources can be analyzed and made accessible by creating a 'mapping' of reads and writes of 'data points' through their operations. In other words, by mapping the read-write interactions of individual instructions using appropriate representations (and, alternatively, graphical representations), they can be used for numerical optimization techniques, enabling the automatic parallelization of source code and consistently producing runnable concurrent code. Several methods exist to access these interactions, but none can map the read-write patterns of source code to the data introduced by the programmer-chosen variable definitions, then continue extracting the desired sequence chains and introducing potential communication patterns, thus "mapping" the code to a broad hardware infrastructure. This method discloses a novel approach to “adapting” source code to a given hardware infrastructure (FPGA, CPU, GPU, cluster, etc.) at all levels.
[0036] Another advantage of this invention is that the disclosed methods and systems can solve known technical problems, such as solving nested loops with arrays, thereby providing a new perspective on well-known problems arising in the optimization steps of PDEs (Partial Differential Equations) or SOTA compilers. This method offers a new perspective on code, and this new scope is based on the physical effects occurring in all classical computing infrastructures, resulting in a general approach that maps computation to a given hardware architecture and derives a concurrent representation of code on ideal hardware for a given hardware or given code. This is based on preserving all "read" and "write" dependencies of the introduced data nodes and constructing instruction chains based on these dependencies. By extracting these instruction chains, the minimum bit size of the instruction chain used for computing the target platform is extracted. Since each instruction chain can be represented as a combinational circuit (the output depends only on the current input), these instruction sets represent combinational circuit blocks. Instruction chains in the same column can be processed in parallel, subject only to the physical properties of the delays, which are corresponding limitations of binary computation (the delay between applied voltage and a stable result).
[0037] The resulting computational block nodes and their flowcharts are returned as well-formatted bases in matrix form, thus generating a general method for obtaining code applicable to different computing units (e.g., CPU, GPU, FPGA, microcontroller, etc.). This method offers a new perspective on ICT software and hardware interactions that follow the principles of systems theory. This leads to methods that can bring novel solutions to a wide range of fields, such as: (a) Adaptive Hardware-FPGA (Field-Programmable Gate Array) / ACID (Atomicity, Consistency, Isolation, Endurance): This invention decomposes code into chains of instructions that clearly represent logical elements in an integrated circuit. Because this method provides a general form for optimizing the combination of computation and communication, it can be used to optimize instruction sets based on the same "bit pattern" / "signal," leading to novel approaches, for example, to optimize automated transfer from software to FPGA or to bridge the gap between code and chip layout planning. (b) ML (Machine Learning) / AI (Artificial Intelligence): Machine learning and artificial intelligence code requires significant resources, especially during the training phase. For example, this approach can be used to (i) optimize known code, (ii) support code development that adjusts its complexity during runtime, making it difficult to parallelize in advance (because this approach always produces optimized code), and (iii) support upcoming non-neural network-based (e.g., genetic algorithms, see, for example, R. Farber's) Inside HPC Special Report: AI-HPC is Happening Now (Inside HPC Special Report: AI-HPC is Happening Now) born) The method. (c) HPC (High-Performance Computing) Applications: Because this method can convert code from, for example, Python to C code with MPI support libraries, it can bridge gaps between different research fields (HPC to AI development). Another application could be adaptive mesh refinement implementations for numerical modeling software packages in engineering applications, weather forecasting models, etc. Alternatively, it can be used to combine models with different spatial and temporal resolutions (e.g., computational fluid dynamics models and agent-based models) and improve existing software packages in different fields, such as modeling and analysis packages. (d) Automated Business Processes: This invention can also be used for process management, where determining whether a unit should perform a task or pass it on to another unit is a well-known problem. The method of this application provides a solution to this problem. (e) Cloud, desktop operating systems, virtual machines, general deployments: Enabling a common approach that can “reduce” the code for essential required operations and possible concurrency options, supporting a variety of solutions in the interface between software and hardware. This interface is obviously particularly suitable for any form of operating system, virtualization, and / or software deployment, more specifically, such as virtualization solutions for cloud infrastructure, operating systems (with multi-core systems), virtual machines supporting mixed operating systems, or similar examples. (f) Heterogeneous platforms, (i) IoT and edge computing: Heterogeneous platforms dominate in different domains (e.g., IoT projects, autonomous driving, mobile and cloud application combinations, and other forms of applications running on and / or utilizing hybrid hardware infrastructure). This approach can tailor code to determine how data, computation, and / or data communication are optimally allocated on the platform. Furthermore, it can incorporate the diverse attributes of the hardware components of a given computing unit network during software deployment / development and optimize code to achieve target attributes, such as reducing latency in certain parts of the software system. (g) Embedded Systems: Embedded systems have high requirements for, for example, power consumption or other specific adaptations of given code, such as some microprocessors with only a reduced instruction set or similar challenges. This approach can directly support such mapping because it can be optimized for given physical properties, thus providing the most efficient code representation for any given code. (h) Self-optimizing algorithm: This invention allows for fully autonomous looping, meaning the algorithm can self-optimize on a given platform without any manual interaction. This enables new applications and fields previously unknown to us. Attached Figure Description
[0038] The present invention will be explained in more detail by way of example and with reference to the accompanying drawings, wherein:
[0039] Figure 1The diagram schematically illustrates the formation of latency under different modern computing infrastructures. Microprocessors, based on integrated circuits, allow arithmetic and logical operations to be performed based on two binary values. For this to happen, the binary values must be available to the processor's computational units. The processor unit needs to obtain the two binary values to compute the result of the expression a = b, operand c. The time required to retrieve the data for these operations is called latency. These latency levels are broad, encompassing registers, L1 cache, memory access, I / O operations or network transfers, and processor configurations (e.g., CPU vs. GPU). Because each individual component has latency, the total latency of computation is primarily a combination of the hardware components required to move data from one location to another in modern computing infrastructures.
[0040] Figure 2 A block diagram schematically illustrates a shared-memory multiprocessor as a class of parallel machines, providing the foundation for a shared-address programming model as a top-level parallel programming approach. In a shared-memory multiprocessor architecture, it is assumed that the computer system allows processors and groups of I / O controllers to access a collection of memory modules via some form of hardware interconnect. Memory capacity can be increased by adding memory modules, and I / O capacity can be increased by adding devices to I / O controllers or adding additional I / O controllers. Processing power can be increased by waiting for a faster processor to become available or by adding more processors. All resources are organized around a central memory bus. Through the bus access mechanism, any processor can access any physical address in the system. Since all processors are considered, or practically, equidistant from all memory locations, the access time or latency at memory locations is the same for all processors. This is called symmetric multiprocessing.
[0041] Figure 3 A block diagram schematically illustrating the UMA architecture is shown. In the UMA architecture, all processors uniformly share physical memory. All processors access all memory words at equal time. Each processor may have private cache memory. Peripheral devices also follow the same rules. When all processors have equal access to all peripheral devices, the system is called symmetric multiprocessing. When only one or a few processors can access peripheral devices, the system is called asymmetric multiprocessing.
[0042] Figure 4 A block diagram schematically illustrates a NUMA multiprocessor architecture. In a NUMA multiprocessor architecture, access time varies depending on the location of the memory word. Shared memory, physically distributed across all processors, is called local memory. The collection of all local memories forms a global address space accessible to all processors.
[0043] Figure 5A block diagram schematically illustrating a COMA multiprocessor architecture is shown. The COMA multiprocessor architecture is a special case of the NUMA multiprocessor architecture, in which all distributed main memory is converted into cache memory.
[0044] Figure 6 Block diagrams are shown schematically illustrating different ranges of the unit "basic block" (or "block unit," respectively) and "computation block node" as illustrative examples. The "computation block node" used in this application is fundamentally different from the block unit used in the SOTA (State-Of-The-Art, latest) compiler.
[0045] Figure 7 A block diagram is shown schematically illustrating a simplified but more realistic example, in which the inventive method takes advantage of the fact that logarithmic instructions (FYL2X as an example on modern CPUs) require much longer instructions than floating-point addition and / or multiplication instructions (e.g., FADD, FMUL). The inventive method translates statements 'x:=a+b' and 'y:=a...' into... b' is added to two different computational block nodes (cbn) because both are based on the same information 'a' and 'b'. Since the 'log2(x)' statement uses information 'x', the 'log2(x)' statement is appended to 'x=a+b'. Information 'y' is being transmitted, so this information can be used in two independent computational chains.
[0046] Figure 8 It shows how to Figure 7 The code in the example is broken down into machine code that can be executed on two computing units synchronized through any form of IPC (it must be noted that IPC means more about communication between two computing units than "InterProcess Communication"). The matrix indicates the clock cycles required to compute different machine instructions, as an example of how the computation time values of the instructions are obtained. In this form, in Figure 8 As can be seen, Unit 2 can calculate the long execution instruction of the statement 'log2(x)', while Unit 1 processes the loop and increments a ("a=a+1"). See [link to documentation]. Figure 7 .
[0047] Figure 9A block diagram schematically illustrates the inventive method, which forms two matrices, referred to herein as “numerical matrices,” from the flowcharts of computational block nodes (note that, as a variation, “numerical” may also refer to textual data in certain contexts, since all data on IT infrastructure can be understood as low-level numbers, such as binary). One matrix contains the instruction chain, and the other contains possible transport attributes (from and to other computational block nodes). Thus, the code extracted from the matrices always forms a “computation -> communication” pattern, as detailed in the following paragraphs. Clearly, if the code is mapped to a single unit, the communication portion disappears (while the computation (= instruction chain) is added), and the inventive method simplifies to a method with “basic blocks,” each processable by a state-of-the-art compiler. Furthermore, the matrices representing information access forms that are more scalable than graphs respectively demonstrate the well-formed nature of control flow graphs. The definition of computational block nodes (cbns) also indicates the general nature of the inventive matrices: in one matrix, each row has an independent instruction flow (= computation), while in the other matrix is the desired transport (= communication) to other cbns. Therefore, this ensures that: a) all instructions in the computation block node do not require further information; b) the information used in the same computation step throughout the code does not change anywhere else; and c) only information unaffected by the computation in this time step is transmitted.
[0048] Figure 10 A block diagram schematically illustrates how each row of the computation matrix and transfer matrix together represents a combination of instruction chains and communication entries for a unit. The unit depends on the implementation level (e.g., raw component, thread, process, compute node, etc.). Clearly, empty computation units or unused communication entries (empty units in the computation and / or transfer matrices) disappear, and start and end communications are linked together, as shown... Figure 10 As shown.
[0049] Figure 11 A block diagram schematically illustrates a possible optimization of the system of the present invention, which provides optimized ideal hardware for technical computation and processing problems. The most obvious approach to this optimization is by constructing different row combinations from the computation and transfer matrices, with each combination being a possible new parallel / concurrent code (since transfers on the same unit disappear while computations are added), and then evaluating its properties on the target infrastructure, such as... Figure 11 The example shown is simple.
[0050] Figure 12 A block diagram schematically illustrates an exemplary multiprocessor system 2 having two or more processing units 21 (multiple processors), each processing unit 21 sharing main memory 22 / 221 / 222 / 223 and peripheral devices 25 to process program code 3 simultaneously.
[0051] Figure 13 A block diagram schematically illustrates a variation of an exemplary embodiment of the invention, wherein source code 31 serves as input code for an automatic parallelization compiler system 1, which includes a parser 11, a computational block chaining module 14, a matrix builder 15, an optimizer 16, and a code generator 17. The automatic parallelization compiler system 1 generates parallelized and optimized target code 32 as machine code or assembly code for execution by a parallel processing system 2 having multiple processing units 21.
[0052] Figure 14 A block diagram is shown schematically illustrating an exemplary compiler system known in the prior art compared to the automatic parallelization compiler system 1 of the present invention.
[0053] Figure 15 A block diagram schematically illustrates exemplary basic elements of a tree structure and / or computation graph, respectively. The computation is simplified to a single type of statement: `result = param1 operation param2`. Numeric operands are +, -, ... From a numerical perspective, these are unique. In the source code 31, which is a high-level language, values are assigned to variables in the form of variablename=value. This is a link to a "virtual" location (at variablename) to store the value. Source code 31 is generally sequential—this is the programmer's way of thinking. According to the invention, the code is processed in a different way; the invention views the code as savelocation1 = savelocation2 operation savelocation3. Based on this, a basic graph or tree structure element is introduced here, which, for example, has two input data nodes 33 / 331 / 3311 (datanode). in1 and datanode in2 ), operation node 332 and output data nodes 33 / 332 / 3312 (datanode) out They are connected by directed edges, such as... Figure 15 As shown. As used in this paper, node 33 is the basic unit of a data structure, such as a linked sequence of processor instructions (computation block node 333 / operation node 332) or a tree data structure, serving as a data input or data output structure (datanode). in / datanode out Node 33 contains data and can also be linked to other nodes 33. Links between nodes 33 are typically established in [the following context]. Figure 15 The diagram is indicated by pointers (arrows).
[0054] Figure 16 A schematic diagram illustrating the basic elements of the source code is shown. In the lexical analyzer and parser 11, high-level language operations are simplified to basic graph or tree structure elements. Therefore, the following can be used: (i) arithmetic operations: +, -, (ii) Logical expressions, such as conditions: a==b or a>=b or similar conditions that result in a true or false output, (iii) variable assignment name=value, (iv) flow control operations, such as (1) branching expressions, such as if(condition){block1}, and (2) looping expressions, such as loop(condition:increment variable:maximum value of increment variable){block1}. Similar to basic operations in assembly code, the instruction set in processor 21 typically has 3 parameters. Statements and basic graph elements describe the two reads (datanodes) following the operation (operation node 332). in1 3311 and datanode in2 3312) and one-time write access (datanode) out 3312). Multiple assignments to a variable name will produce different versions of that variable and generate different data nodes (331). For example... Figure 17 As shown, each version will build a new data node 331.
[0055] Figure 18 A block diagram schematically illustrates an exemplary simple operation sequence 332 in a tree structure or graph. Sequences of program code 31 can be added to the tree structure or graph statement by statement. Complex expressions are simplified (due to the need to simplify computations on a binary computing system to this form) into a series of expressions of type result = param1 operandparam2 (result = param1 operand param2). If an operation node 332 accesses a data node 331 that another operation node 332 is writing to, the sequence is constructed by connecting these operation nodes 332 through directed edges (next edges). This method... , Writes and reads are mapped to a tree structure or graph of all data nodes 331 (see...). Figure 19 As a rule to simplify the following steps, only one write to data node 331 is allowed (this helps simplify subsequent operations on the graph). Otherwise, a new operation 332 will be introduced to model multiple writes to data node 331.
[0056] Figure 20 The diagram illustrates △t. readwrite 35 / 351 is a block diagram describing the time between write and read accesses to data node 331. Through this explanation, the latency Δt... readwrite351 can be viewed as a number representing the time required for data node 331 to be transferred to another process in multiprocessing system 2. △t readwrite The interpretation of 351 depends on the level of hardware settings. It represents the technical and physical time difference between write access (I / O processes, network cards, etc.) and read access. △t readwrite 351 is a unit provided by the hardware infrastructure. △t readwrite 351 can be composed of different Δt: Δt total =△t1+△t2+△t3+△t n (For example, L1 cache access - memory access). For 1-dependency (from 1 dependent datanode) in (Read operation node), respectively give △t readwrite 351, and it must be very short. Note that if 2-dependencies exist, other issues arise, which will be discussed below.
[0057] Figure 21 A block diagram schematically illustrates the dependencies between basic tree structure elements and graphical elements, respectively. As a variation, it would be easier to set a rule that only one operation node 332 writes to one data node 331. Then there are different but limited cases for adding new operation nodes 332 sequentially: (i) 0-dependency: placement: independent; (ii) 1-dependency: placement: after dependent operation node 332; (iii) 2-dependency of two data nodes 331 (3311 in 1 and 3312 in 2): -unclear -> Δt readwrite 351 depends on the history of its previous operating node 332; at this point, in order to find △t readwrite 351, it is necessary to know the datanode in1 3311 and datanode in2 All previous △t of 3311 readwrite The history of 351. △t readwrite The history of 351 must be related to △t latency Compare 352, △t latency 352 is the time required to distribute information or data points to another location via System 2.
[0058] Figure 22 A diagram is shown schematically illustrating how data / information can be exemplified, for example, data can be transferred from one process to another, or in the case of threads, simultaneous writes can be prevented. For example, moving data can be viewed as a basic operation (operation K), and the transfer will last Δt. latency 35. It is important to note that △t latencyThe interpretation of 35 largely depends on the hardware system and can be viewed as the time it takes for data / information to be transferred through the system. Furthermore, if the system allows, for example in the case of Direct Memory Access (DMA) network transfers, operational nodes unaffected by the transfer can be computed during this period. Or, in the case of a multi-threaded system 2 (where two or more processes can access the same data, but race conditions are critical), this △t... latency 35 can be viewed as a block of time, where one process reads / writes corresponding data while other processes are not allowed to read / write. (See also: Transfer) Figure 23 This can be viewed as transferring information or data from a source to a target location via System 2. The transmission mode (e.g., sending and receiving) is not explicitly defined, and it is not specified whether transmission is required in the final code, therefore it will not disappear. This can only be achieved after optimization of the corresponding platform / hardware infrastructure.
[0059] Figure 23 A block diagram schematically illustrates exemplary computation block nodes 332 / CB1, CB2, ..., CBx. Computation block nodes 333 can be introduced as follows: (i) a computation block node 333 consists of connected operation nodes 332; (ii) operation nodes 332 form a chain 34; (iii) a computation block node 333 can be connected to the next computation block node 333 or control flow node 334, for example, a branch node 3341; (iv) Δt computation 352 is the time to compute all operation nodes 332 (representing instructions) in computation block node 333, and (v) has a minimum length: Δt latency 35. During this period, data may be transferred within the computing infrastructure, and (vii) for the purpose of describing communication, a transmission is introduced, which includes: (a) source: the location (start, end) in computing block node 333, computing block node 333 id, operation node id, datanode in1 / datanode in2 3311 or output data node 3312, (b) Objective: Calculate the position (start, end) in block node 333, calculate block node 333 id, operation node 332 id, datanode in1 / datanode in23311 or output data node 3312. Transmission must not be an explicit send and receive of information -> Computation block node 333 can begin sending and / or receiving data information at the beginning and end of block 333 (before and after all operation nodes 332 have been computed) -> This model is typically used in explicit non-blocking send and receive communication methods (e.g., Message Passing Interface (MPI)), where sending and receiving can be performed independently of computation (e.g., via Direct Memory Access (DMA) network cards). However, by explicitly introducing operation nodes with send and receive operations (and then having their own Δt)... readwrite 351), block sending and receiving work in the same way. If, for example, communication is not allowed in a multithreaded method (where threads share the same data, but time dependencies can only be guaranteed by locking mechanisms), then sending and writing can be interpreted as setting and releasing locks, and Δt must be interpreted accordingly. latency 351.
[0060] Figure 24 A block diagram schematically illustrates exemplary processing of program flow control elements in a tree structure or graph. Condition node 335 is based on the following implementation: (i) each condition in an if condition or loop condition creates a new "level," e.g., cond:0->cond:1; (ii) each condition knows the number of levels between its own given level and the program's base level (condition 0) (e.g., via cond:0->cond:1->cond:2, meaning two conditions are computed to reach this position in the code); and (iii) condition node 335 is connected via directed edges to branch nodes 334 / 3341 with the same condition. Branch nodes 3341 are further introduced: (i) each condition has at least one branch node 3341; (ii) each branch node 3341 is connected to the computed block node 333 belonging to this branch (the code in the if clause section). Conditions are generated by operation nodes 332, which have (logical) expressions with "condition" results (e.g., true or false). Introducing conditions is a method to determine which computation block node a new operation is assigned to in the "earliest" manner (the computation block node must be in a group at the same condition level, but can be in another branch node). It is important to note that branch nodes do not correspond to the blocks in the branches defined in the "basic block" definition.
[0061] Figure 25A block diagram schematically illustrates exemplary processing of an "if statement". An if statement causes a code branch under a condition (if (condition) {codeA}). The result of the logical conditional expression that needs to be transmitted in the system -> a subsequent empty computational block node 333 is added after the computational block node 333 containing the logical command -> this is the time required to transmit the comparison result (i.e., the condition) to other processes -> it can be used to compute other things – this computational block node 333 can be labeled as branch transmission type (CB2). Subsequently, two directed edges of CB2 333 are added to a new branch node, which has a new computational block node for the code in branch 1 and a so-called hidden branch node (see below), which is used if the condition is not met (but it is not an else clause, however it can be). The result of the conditional expression must be transmitted to the subsequent branch -> a transmission packet is added to the end of CB1. Edges from the branch node and hidden branch node 3342 can only be set after all statements in the branch code section have been parsed, thus after the closing statement of the if condition (see below).
[0062] Figure 26 A block diagram schematically illustrates exemplary processing of nested "if statements". Since each statement in the code is added to the graph in the order it is read, the control edge connection between branch node 3341 and subsequent branch node 3341 is only completed after the end marker of the if statement -> nested if statement is reached. The correct condition node 335 with the correct branch node 3342 can be found by calculating the last condition level (reduced using the closing if statement) and traversing the graph to the correct node 33.
[0063] Figure 27 A block diagram schematically illustrates exemplary processing of nested "loop statements". Note that the loop statement can be processed with some adjustments, based on the branching described above for the if statement. A loop statement causes a branch in the code as long as a condition is met; in this example, this is done by incrementing a variable until a certain value is reached (loop(condition, i, 2) {codeA}). This is the same as the if statement -> add CB4 333 for a transmission of type loopbranch-transmission. Add the increment operation node 332 to the variable defined in the expression. The result of the conditional expression needs to be transmitted to the subsequent branch -> add the transmission packet to the end of CB3 333. An edge from the computation block node 333 of the transmission type and the branch node 3341 (branch2) following the loop branch node 3343 (branch1) can only be set after the end statement of the loop statement (see below).
[0064] Figure 28 A block diagram schematically illustrates exemplary processing of nested loop statements. Since each statement in the code is added to the diagram in the order it is read, the control edge connection between the loopbranch-transmission type computation block node 333 and the subsequent branch node 3341 can only be completed after the end marker of loop statement -> nested loop statement is reached. This can be accomplished by finding the lower condition level based on the last added statement and locating the correct loop branch transmission node 33. The computation block node 333 with comparison and increment operation nodes 332, as well as the loopbranch-transmission type computation block node 333, needs to be reconnected to the earlier loop branch node 3341. The connection of the branch node after the loop also needs to be updated. branch0 | cond0 for (i=0; cond1; i++) {branch1 | cond1 for (j=0; cond2; j++) {branch2 | cond1 -> cond2 for (k=0; cond3; k++) {branch3 | cond1 -> cond2 -> cond3} branch4 | cond1 -> cond2 } branch5 | cond1 } branch6 | cond0
[0065] For variable assignment, the assignment is also an operation node, but for a=0 and a=b, there is only one data node (in1) instead of two (in1 and in2): (i) a=0 (-->variable name=number): - 0 dependency and 1 dependency can occur, (ii) a=b: - A copy operation node must be added because data is explicitly copied from the data node to another data node with the correct version number, - It must be a 1 dependency, (iii) Redefining the variable name results in a new version of the variable and a new data node 331. Furthermore, array and pointer variables can be handled in a similar way.
[0066] Figure 29 A block diagram schematically illustrates exemplary processing of branching and variable versions. Because the compiler views the code from a clear data-centric perspective, explicit changes to the data under certain conditions are not necessary. Figure 30In the code, under condition cond0, c is evaluated in branch 0. Under condition cond0->cond1, c is redefined in branch 1. If the comparison function in CB1 is false, the program flow reaches the hidden branch node 3342 hbranch1, which copies the value from the data node @position mmapid:12 (the data node where c=1+5) to the new position, just as the value in CB3 is true. This is important and is why hidden branch nodes exist; it's not (only) else statements. The above operation must be performed because the programmer writes the data flow for the true condition, not for the false condition (which is not expected to happen), but this is incorrect in the data dependency graph because c=8 in branch 1 performs a new version operation on the variable during code parsing. Furthermore, this operation must be performed for every variable assignment under the condition.
[0067] Figure 30 A block diagram schematically illustrates an exemplary process of branching and transfer. In this case, when a 1-dependency or 2-dependency occurs under different conditions -> different branch nodes, it means that a transfer of information must occur beforehand at the branch node. The same applies to 2-dependencies with the same conditions but different branch nodes. However, there are other possibilities to address this issue. This implies the need for data transfer to the new computational block node within the corresponding branch node. Therefore, branch nodes can also be handled in other ways.
[0068] Figure 31 A block diagram schematically illustrates exemplary processing of arrays and dynamic arrays. An array can be viewed as a sequence of basic variable names and offsets (e.g., pointer variables and offsets in C) of equal length. Therefore, it can be processed in two steps: finding the address / location of the basic variable and obtaining its offset, then going to the offset found in the variable definition (type / length, e.g., u_int8 <-> u_int32). It's worth noting that in this particular case, the operation isn't actually directly based on the CPU's basic instructions, as these are executed by the processor itself by first performing lookups in the L1-Ln caches, etc.
[0069] Figure 32A block diagram schematically illustrates exemplary splitting and merging scenarios for compute block nodes 333. In the case of a 2-dependency relationship, a merging scenario of two compute blocks 333 is required. If two operating nodes read from the same data node, this will create a splitting scenario of two compute block nodes 333. For both scenarios, by introducing a new compute block node 333 (e.g., a merged transport or a split transport), the two compute chains 34 (compute block node chains) can be split or (re)connected by sending transport data / information via the system. Transport information is added to the newly created compute block node of the transport type.
[0070] Figure 33 A block diagram schematically illustrates an example of how to narrow transmission gaps in a graph flow. This step only occurs after all statements in the source code have been added to the graph. Then, additional computational block nodes of type b2b transmission are added to the branch nodes not connected via computational block node 333 of type transmission. This is necessary for propagating branch changes through the system. In later steps, these transmission blocks must be set to the latest block number (computation step) so that information about branch changes can be propagated through system 2.
[0071] Figure 34 A block diagram schematically illustrates an example of introducing a time perspective into a tree structure or graph. From the connected operation node 332 and flow control computation block node 333, the tree structure or graph can be viewed as having Δt computation 352 computation blocks, 333 chain, 34 。 Within each computation block node, operation nodes are grouped, therefore Δt readwrite 351 is "optimal" (in a locality sense, therefore copying data is slower than computing it). These sequential chains within computational block nodes should not be shuffled, as they represent sequential parts of the code. For parallel code, computational block nodes need to be balanced over time so that two incoming computational block node chains (and therefore operation chains) are balanced with each other -> therefore, in the fusion case, the two incoming chains must have the same runtime. Otherwise, the overall computation will stall, requiring the computation of the other chain. If, in all fusion cases of computational block node 333, the incoming chains (CB1 and CB2) have the same runtime and start time, then the most concurrent / optimal parallel code is achieved. In the split case, different chains can be started simultaneously, thus creating parallel computation. It is important to note the series of "+" and certain conditions of " "This might occur within computational block nodes, and they can be further split into parallel computations. However, this is easily detected during the optimization phase. Each computational block node requires Δt." compute Let's calculate all the operation nodes 332. Now we can try to balance Δt. compute And the system can use △tlatency 35, because each computational block node 333 can be considered as the minimum Δt. latency 35 is quite long, as described in the previous steps. This is achieved by assuming that each computational block node 333 must have at least Δt. latency A length of 35 allows for data transfer within System 2. A finite numbered block can be introduced for each computational block node. These represent the desired sequence of computational blocks 333 in the sequential chain 34 of operation node 332. This generates a unique and well-defined grouping graph where each group of operations has a unique number, and transformations based on these numbers can be performed to bring them into matrices. These matrices can then be used (e.g., using real-world time) to optimize / map to a given or desired infrastructure.
[0072] Regarding assigning runtime numbers to block graphs or tree structures, numbering can be implemented, for example, as a recursive function, resolving the graph of computed block nodes and their edges node by node. In each branch node 3341, begin numbering computed block node 333. Then, recursively traverse the chain 341 of computed block nodes in branch node 3341. After a branch node, given the computed block nodes in that branch node, the highest block number is known. This is used for the next branch node. The rule is that computed block node 333 steps to computed block node 333. If there is only one or no preceding computed block -> set the block number to the actual block number and increment the block number (for the next computed block node). If there are two preceding computed block nodes -> this is a merging case -> if this is the first time the node is visited -> append to the local list of block numbers. Otherwise, if this is the second visit -> use the highest block number (actually from the function call or stored in the node list). If there is one subsequent computed block node -> call the function of the computed block node (recursive method). If there are two subsequent computed block nodes -> split case -> recursively call the numbering functions of both computed block nodes. If there is no next computation block node (and therefore no next computation block node) -> if there is, return to the next branch node and complete the actual recursive call. By appropriately adjusting the block number in the branch node transmission, the call graph is based on the computation block node connection numbering in the form of a discrete-time graph, where each computation block node has a finite number and must be computed within the same time period.
[0073] Figure 35 A block diagram schematically illustrates an example of splitting a graph into a single / "transmission-coupled" call chain. In this case, the call graph or tree structure can be split into a single chain 34 of computation block nodes 333, resulting in a single series of operation nodes, where each computation block node 333 has corresponding transmission information. Each computation block node has a unique number. The required transmissions / communications are stored within the computation block nodes.
[0074] Figure 36 and Figure 37 A block diagram is shown schematically illustrating an example of a possible process from transmission to directional communication. The direction of communication may depend on the numbering of the compute block node 333, such as... Figure 36 and Figure 37 As shown in the example. It must be ensured that all transport computation block nodes are located at the highest +1 block number within a branch node (to ensure sufficient time to propagate program flow information to all computation units / processes). Transport packets with source and destination information must be explicitly transmitted to send commands in the correct computation block nodes. The receiving portion can only be completed after the optimization step. Signal transmissions (e.g., branch or loop transmissions) must be implemented to the next computation block node 333 for all connections within the corresponding branch.
[0075] Figure 38 A block diagram schematically illustrates an example of the process from graph to matrix. At this point, the graph consists of branch nodes of a single chain 34 with computation block nodes 333. Each computation block node 333 knows which information (data and / or signals) must be transmitted to which other computation block node 333. Each computation block node 333 has a discrete number representing the order in which each block must be computed during program execution. Therefore, the graph can be interpreted as a matrix where each cell is a computation block node, each row is a single cell, each column is a discrete block number (sequence number), and each cell (computation block node) knows which information must be sent to other computation block nodes 333 (cell entries). Each cell knows which operations (operation node chain) must be computed during its block number and in what order—they are independent and must be performed in the correct order -> with clear recent write and read connections. Each operation node knows the correct global data required for reading (in1 and in2) and writing (out). It is now possible to optimize matrices (e.g., numerically) for target hardware infrastructure (CPU, CPU with explicit network transfer (e.g., via MPI), GPU (memory transfer, then vectorization operation), etc.).
[0076] Figure 39A schematic diagram illustrating exemplary program paths and matrices is shown. The z-axis dimension is the code perspective through each path of the code (each conditional change introduces a different path through the code). The third dimension (or z-dimensional) is the conditional switch, meaning that each set of transfer and computation matrices is a path through the code under one condition. From this perspective, each path through the code can be represented by two matrices, where rows represent independent chains and columns (x-axis and y-axis) represent block numbers. Branching develops by switching to the corresponding z-dimensional matrix set (the path through the code), and each process node needs to know all its own possible chains. In this description, each conditional change is captured by a set of computation and transfer matrices, but matrices can also be viewed as tensors, and then, for example, computation and transfer tensors could contain independent operations corresponding to the transfers in their rows, discrete computational steps in each column, and different conditions in their third dimension. Alternatively, everything could be packaged into a single tensor, combining computations and transfers for each block number, unit, and condition, etc.
[0077] Regarding optimization, there are many applicable automatic optimization techniques: merging lines to reduce parallelism, moving individual operation chains to the earliest point (sending commands in a unit acts like a barrier), reducing communication through optimal line combinations, etc. Compiler system 1 can be used to obtain runtime estimates of unit entries, or methods such as Agne Fog from the Technical University of Denmark can be used to extract CPU and cache interactions, or tables from CPU manufacturers can be used, or compilation can be done using OpenCL, etc. Various optimization techniques exist in the technical field to map matrices to the target infrastructure. For example, in the perspective of a tensor for computation and a tensor for transfer, different parallel code versions can be retrieved by combining the same lines in each tensor, thus generating a new "computation and transfer" combination for each block number. This will result in a reduction in the number of parallel / concurrent units. By merging lines, transfers can be reduced or grouped (in the final code communication) and computations can be added. If there is no send() or read() at the beginning of the block, the operation node in the block can be moved to the previous block. Each unit knows the amount of data (memory, etc.) it needs. Different given Δt on the target platform latency35 can be used to determine which sequential part (cell entry in the computation matrix) must be computed at which hardware cell. The type of communication in the infrastructure can be implemented as needed, ranging from asynchronous or non-blocking to explicit blocking send and receive commands in MPI frameworks, preventing race conditions by ensuring proper setting and releasing of barriers, to batch copy transfers in GPU infrastructures, etc. Therefore, optimization techniques can be easily selected by choosing appropriate existing optimization techniques, such as using a state-of-the-art compiler for each piece of code (computation and transfer) per cell. The optimization technique used will introduce a broader perspective to obtain code that is more "perfectly parallel" than other techniques (perfect on the average linear dependency of speedup on the number of processes with a slope of 1). Therefore, the matrix can be numerically optimized to obtain new parallel and optimized / concurrent code for the target hardware. This can be done automatically, thus representing a significant advancement compared to other methods. Because this is done by software, the software can now parallelize its own code, which is new and brings new possibilities, such as adaptive models in machine learning (ML) or artificial intelligence (AI) applications, particle sources in grid or eddy current methods in computational fluid dynamics (CFD) calculations, or combining different model methods with different spatial and temporal resolutions (finite volume method (FVM) with agent-based models and statistical models), etc.
[0078] Figure 40 A block diagram schematically illustrates example code extraction. Code can be extracted from a matrix in several ways: directly extracting assembly code, writing code files and compiling them with a state-of-the-art compiler, or explicitly implementing send and receive methods, such as for a message passing interface (MPI). Matrix computation units have statements in the form of code = operation, and each column must be computed within “equal” time intervals, with each row being a separate process. Matrix transmission units know which information must be shared with which other units.
[0079] Figure 41 A schematic diagram is shown illustrating the computation block node (CB) for a double recursive function call, its operations, and the corresponding data nodes (similar to the labels in Table 1).
[0080] Figure 42 A block diagram is shown schematically illustrating a function recursion call that leads to additional transfers. This indicates a transfer to a location within a compute block node (the start or end point of the compute block node).
[0081] Figure 43 , Figure 44 and Figure 45 A block diagram is shown, schematically illustrating the steps of numbering computation block nodes according to their call location in the code, thereby producing, as... Figure 43The schematic representation of the pseudo-image in the middle, in turn, produces, as Figure 44 and Figure 45 The diagram shows the computation and transfer matrices for each path number. Viewed as an m × n object, a set of computation and transfer matrices is created for each path number, resulting in 2 computation and 2 transfer matrices. Path (or condition) switching can be performed... Figure 46 As seen in the image, it indicates whether the signal is 'true' or 'false'.
[0082] Figure 46 A block diagram is shown, schematically illustrating the result of combining the start and end communication units in the transfer matrix, eliminating empty units in the computation matrix (for each path), and bringing them back to different code segments. Based on this code segment, code can be generated directly (as a compiler) or the code can be transferred back to the compiler and then machine code can be generated using a SOTA compiler (as a transpiler), for example, using unit-specific optimization techniques implemented in the SOTA compiler, which are primarily compiled for a single unit.
[0083] Figure 47 A block diagram is shown, schematically illustrating how to process function calls in parsed code using the presented methods. After the parsed function is defined, the generated computational block node (or matrix entry) can be "copied" / used at the location where the function is called.
[0084] Figure 48 A block diagram is shown, schematically illustrating how the method of the present invention maps and / or optimizes code with a more concurrent solution than the input code. As shown, the optimized code is a combination of lines, and the diagram illustrates the combination of cbn in the branch node labeled branch2b (see [link]). Figure 43 And combine them together, see Figure 48 Calling a function involves placing the computed block nodes in the correct positions within the matrix to apply the corresponding transfers, such as... Figure 47 As shown. With this in mind, recursive function calls can be viewed, through the method of this invention, as the transfer, 'reading,' and 'writing' of function parameters and result variables in the return statement, see [reference]. Figure 48 .
[0085] Figure 49 A block diagram is shown, schematically illustrating an example of a function call used to compute the Fibonacci number of input 4 (fib(4)), and step-by-step explaining how additional computation block nodes and reduced transfers (since all transfers are on a single computation chain) produce more optimized source code.
[0086] Figure 50A block diagram schematically illustrates step 4, which shows the CBN call in the case of 'n=4'. Since recursive calls are very easily detected in the code, it's easy to avoid fully implementing recursive calls in the final application, such as... Figures 49 to 53 The diagram is simplified as shown below, where the depth of the chain depends directly on the number n in fib(n).
[0087] Figure 51 A block diagram schematically illustrates step 5, which shows the transfer that will occur (transferring the information from the last "write" to the data node to the location where the data node is "read" and remembering the information in the corresponding compute block node).
[0088] Figure 52 A block diagram is shown, schematically illustrating that because all computations are on a single chain, transmissions disappear, as... Figure 52 As shown.
[0089] Figure 53 A block diagram is shown, schematically illustrating that this will result when solving each step. Figure 53 A program in Chinese format.
[0090] Figure 54 A block diagram is shown, which schematically illustrates that function calls and therefore recursive calls can also be interpreted as array operations applying the method of the present invention, since it transmits information (function parameter param[i]) to the corresponding cbns in the branch node of the function declaration, and then passes the return value back to a[i].
[0091] Figure 55 and Figure 56 A block diagram schematically illustrates how to solve the 2D heat equation in Python. Each entry in the array is a data node. In the method of this invention, a read from the array index is an operation node with an indexed data node and the base address of the array. Array operations can be viewed as operation nodes with corresponding data nodes; see [link to relevant documentation]. Figure 56 .
[0092] Figure 57 The diagram illustrates an operation on an array a[i+ A diagram showing the corresponding computed block node for the example of a circular array iw]=a[i].
[0093] Figure 58 The initial block is shown schematically. Figure 55 The detailed block diagram shown in the figure is as follows: Figure 58 As shown.
[0094] Figure 59A block diagram is shown, which schematically illustrates the derivation of the model method by using 1D array notation and applying the basic rules of the method.
[0095] Figure 60 A block diagram is shown, which schematically illustrates array operations such as those in a j-loop. Figure 55 Statements such as ) generate five computational block nodes: one for "reading" the array, another for calculating the arithmetic solution, and a third for writing to the array at position [k+1][i][j]. This representation is a schematic perspective to more clearly show how the method considers this array operation, thus generating Figure 60 The situation shown in the figure.
[0096] Figure 61 A block diagram schematically illustrates the scheme, which can be derived from the fact that each loop thus creates a new computational block node with a "read" or "write" operation node and a corresponding transfer. Therefore, each loop iteration introduces computational block nodes, forming a chain of read, compute, and write steps for a single unit (the unit for later computation operations). If "write" and "read" dependencies exist between these computational block nodes, transfers are introduced, see [link to relevant documentation]. Figure 62 .
[0097] Figure 62 A block diagram is shown, which schematically illustrates how offsets in the indices of "read" and "write" operations can lead to transfers between compute block nodes that contain "read" and "write" operation nodes.
[0098] Figure 63 A block diagram is shown, schematically illustrating the conclusions drawn from the dependencies of "reading" and "writing" to data nodes of an array indicated by an index in a loop.
[0099] Figure 64 A block diagram is shown, schematically illustrating the dependencies between "read" and "write" operations within "read" and "write" compute block nodes, and utilizing methods such as... Figure 55 The three nested loop implementations shown are generated by the loop size (in this case, the mesh size) of the 2D thermal equation with a central difference scheme.
[0100] Figure 65 A block diagram is shown, schematically illustrating that for a nested loop, and for each nested loop, rules can be derived to handle gaps and their impact on the "transitions" in the proposed model. Gaps, caused by loops not traversing the complete array / grid / dimension, are denoted by j0 and Bi in the loop definition.
[0101] Figure 66A block diagram is shown, schematically illustrating how the transmission pattern of the discretized equation can be derived by combining gaps created through iterative traversal of array subsets, and how a model can be built for the transmission, depending on the gap size and the size of the loops (in this case, the grid), which are represented by computational block nodes of the method of the present invention. The method can also be applied to each iteration of each loop, adding the corresponding elements to the graph / tree structure, but this may introduce performance issues and prevent the method from being applied to large problems (e.g., large grids).
[0102] Figure 67 A block diagram is shown, schematically illustrating a very small example with nX=5 and nY=4, which leads to... Figure 67 The diagram shows grouped computation and transfer matrices. In the transfer matrix, the arrow "->" indicates receiving information, and "<-" indicates sending data to other computation block nodes.
[0103] Figure 68 A block diagram is shown, schematically illustrating the transmissions that occur between units, as each unit is represented by a row in the transmission matrix, while computation is represented by the computation matrix. In this diagram, the entries for both the computation and transmission matrices are shown together. It is a combination of computation and transmission matrices.
[0104] Figure 69 The diagram illustrates that it's important to note that this doesn't necessarily mean sending and receiving must occur; it could be shared, for example, by a shared memory segment and protected by barriers or locks, or it could be shared by a cache and therefore lost to CPU processing—depending on the transport / communication mechanism used. This can be transferred to a model, resulting in, respectively, as... Figure 69 The code is in the form shown. Since this method is based on preserving all dependencies of "write" -> "read", and the calculation of the form a[i1] = a[i2] first uses a[i2] to "read" information and then uses a[i1] to "write" information, the first "read" (p0-p1) operation is introduced.
[0105] Figure 70 A block diagram is shown, schematically illustrating how transport can be used to create a time model. Gray represents meta-values (e.g., known from variable type definitions, etc.), which can also be used to map / optimize matrices to a given hardware infrastructure. These values are not used in this example.
[0106] Figure 71 A block diagram is shown schematically illustrating a simple model that is fully analytical, to illustrate possible optimization steps.
[0107] Figure 72A block diagram schematically illustrates the behavior in two different sets of cpuPower and networkLatency, for t = Calculation, combined with cbn CPU Power + Number of Transfers networkLatency can be used to derive this behavior for a grid with nX=2048 and nY=1024.
[0108] Figure 73 A block diagram is shown, schematically illustrating that Fibonacci sources can also be implemented using loops. Based on an example of the 2D heat equation, this produces... Figure 73 The results in.
[0109] Figure 74 A block diagram is shown, schematically illustrating the technical problem of applying the method of the present invention to pointer disambiguation. It can be seen that the method of the present invention solves the disambiguation that occurs when function parameters are passed as pointers, because it treats pointers as information, and this disambiguation is resolved in the step of passing away, as... Figure 74 As shown. Please note that the labels "Intel P5Infiniband" and "Intel Haswell L3-cache" generally represent configuration 1 and configuration 2.
[0110] Figure 75 A block diagram schematically illustrates the corresponding grouping of instructions in the LLVM IR and compute block (CB).
[0111] Figure 76 A block diagram schematically illustrating the formation of the computation and transmission segments is shown.
[0112] Figure 77 The diagram illustrates the situation for n. unit A block diagram of the time model structure for the computation and transmission segment with a value of 3.
[0113] Figure 78 The illustration shows the markings for n. unit A block diagram showing the options for the two units of combination (c1) and combination (c2) = 2.
[0114] Figure 79 The diagram illustrates the concept for a single unit n. unit A block diagram of the runtime of =1.
[0115] Figure 80 A block diagram is shown schematically illustrating the decomposition of code into a matrix or graphical representation.
[0116] Figure 81A block diagram schematically illustrating the formation of the gamma diagram for fib(3) is shown.
[0117] Figure 82 A block diagram schematically illustrating the computation graph with serial and parallel time estimation results is shown.
[0118] Figure 83 A block diagram schematically illustrates three different computation graphs for TT=1, 3, 10.
[0119] Figure 84 A block diagram is shown, which schematically illustrates an embodiment variant using the system and method in the middle of an automatically parallelized compiler, i.e., using the method in a SOTA compiler.
[0120] Figure 85 A block diagram is shown schematically illustrating the decomposition of code into a matrix or graphical representation.
[0121] Figure 86 A block diagram schematically illustrates the combination of CBs and the allocation of results to computational units.
[0122] Figure 87 A block diagram schematically illustrates the distinct computational and transmission / communication components in a gamma diagram.
[0123] Figure 88 A block diagram is shown schematically illustrating the code path of the basic block (BB) and control flow graph (CFD) representation, and having the computation block (CB) of the present invention.
[0124] Figure 89 A block diagram is shown, which schematically illustrates a graph with computational blocks, where an if condition leads to a branch.
[0125] Figure 90 A block diagram schematically illustrates the calculation and communication segment of two units and an if branch.
[0126] Figure 91 A block diagram is shown, which schematically illustrates the loop body in the control flow graph as a read, compute, and write compute block (CB).
[0127] Figure 92 A block diagram schematically illustrates the expanded representation of computation blocks and transfers for i=0-7.
[0128] Figure 93 A block diagram schematically illustrates the loop portion with parallel CB and explicit loop iteration.
[0129] Figure 94A block diagram is shown that schematically shows the loop part data analysis 'A - Parsed' or 'B - Structure' (B model). Obtaining gamma nodes from the data analysis in the loop is an NP - complete problem (A - Parsed). With the introduced embodiment variants of this method, gamma nodes can be obtained from the loop header / latch and statements for accessing random access data structures.
[0130] Figure 95 A block diagram is shown that schematically shows a general structure with CB for an n - nested loop with statements for a random access data structure (e.g., an array).
[0131] Figure 96 A block diagram is shown that schematically shows Case 1 with gamma nodes for 1 read - write dependency in CB.
[0132] Figure 97 A block diagram is shown that schematically shows Case 2 with K reads and 1 write, where K = 2.
[0133] Figure 98 A block diagram is shown that schematically shows having K reads and indicating how to retrieve || and Case 2 with K = 3.
[0134] Figure 99 A block diagram is shown that schematically shows that combining parallel CBs results in unit =2 reduced transmissions and aggregated calculations.
[0135] Figure 100 A block diagram is shown that schematically shows that constructing CB combinations according to read shifts results in reduced transmissions.
[0136] Figure 101 A block diagram is shown that schematically shows that constructing CB combinations according to read shifts produces different functions describing the combination number n comb and the transmission size T.
[0137] Figure 102 A block diagram is shown that schematically shows for [[ID= forty - two]] comb > comb,const the minimum transmission and constant transmission for each CB T,const The transmissions between CBi>3 and i<blocksize - 5 disappear.
[0138] Figure 103A block diagram is shown, which schematically illustrates how, under limited resources, gamma nodes can be evenly distributed across the limited resources by adding transmissions, thereby achieving optimal allocation of gamma nodes.
[0139] Figure 104 A diagram is shown that schematically illustrates structured data and the gaps that occur when the entire array is not iterated over.
[0140] Figure 105 The diagram schematically illustrates a gamma node with CB and each n loop A block diagram showing the transmission after the next iteration and its representation as a gamma node.
[0141] Figure 106 Block diagrams schematically illustrating different possible embodiments EV1 to EV5 are shown. Figure 106 EV1 illustrates the most basic embodiment variant, which forms the basis for all other embodiment variants of the system and method of the present invention, providing automatic parallelization of the code by minimizing the overall latency. Embodiment variant EV1 is based on several fundamental assumptions, including but not limited to: (i) the optimization of automatic parallelization is not limited by the number of available parallel processors (single-core 2103 and / or multi-core 2102), (ii) the latency of memory accesses and data transfers to and from processors 2102 / 2103 is small compared to the processing time required to compute computational block nodes 333 on processors 2102 / 2013, and (iii) the time difference in computing different computational block nodes 333 is negligible. The latter can be assumed based on creative choices of the very basic structure of computational block nodes 333. To optimize limited resources (given a maximum rod dimension), the row dimension can be reduced by constructing combinations. This form of optimization relates to the assumption that: (i) any transfer introduces a significant latency compared to the disappearance of transfers in the transfer matrix. (ii) The differences between transmissions are very small. This means that all transmissions have approximately equal delay times. Assuming (i) and (ii), the maximum row dimension in the computation and transmission matrix defines the combinatorial complexity of the system (a certain number of CBs per BB). According to Wall, David W., " Limits of instruction-level parallelism limit) "Proceedings of the 4th International Conference on Programming Languages and Operating System Architecture Support, 1991, states that each basic block has an average of 3 to 4 ILP opportunities. (i) and (ii) apply to most modern multi-core processors. However, these assumptions may lead to missed optimization opportunities and may limit combinatorial optimization steps, especially for loop parts and / or if (iii) units have dissimilar computational performance and propagation latency."
[0142] Figure 106EV2 illustrates an embodiment variant that includes a process for constructing the task of the invention by combining consecutive computation block nodes 333 with empty cells in the same row of a transfer matrix belonging to (i) the same column of the computation matrix (i.e., parallel executable due to available data) and / or (ii) the same branch node 334 (= computation segment). This allows for automatic parallelization of processor architecture-specific and / or system architecture-specific optimizations, where the number of processors 2102 / 2103, the performance of different processors / cores 2102 / 2103 and / or processor units 21, the size of different memory units 22, and differences in response time, particularly different processor registers 2211 and / or processor caches 2212 and / or RAM units 2213. These hardware-specific structural parameters can be included in the optimization of automatic parallelization, and thus balanced by constructing tasks 36 of different lengths, for example, the number 36i of processed computational block nodes 333 of task 36, where the computational block nodes 333 of task 36 belong to the same column of computation matrix 151, or are consecutive computational block nodes 333 of the same branch node 334, without corresponding entries in transfer matrix 152. This distinction is in Figure 80 It is shown in gamma diagrams a) and b).
[0143] Figure 106 EV3 illustrates the parallelization of the system 1 and method of the present invention for processing data structures with random access in a loop without explicitly resolving data dependencies in the loop portion. Instead, it assesses the impact of affected statements on the read / write dynamics of the data structure accessed with random access and the loop variables used by analyzing the loop head / jump definitions.
[0144] Figure 106 The EV4 (in) Figure 110 (As shown in more detail below) This invention system 1 is illustrated in the application of optimizing integrated circuit (IC) or chip design by addressing electronic engineering problems in IC design by covering the logic and circuit design required for designing integrated circuits or ICs.
[0145] Figure 106EV5 illustrates an embodiment variant of the inventive system for obtaining quantum gates in a quantum computing system. In classical computing, the basic storage element is the bit, which can be either 0 or 1. 0 and 1 are represented at the electronic level as two distinct voltages (see R. Portugal's basic quantum algorithm). To obtain the result of a classical computation, the voltage at the output of the computation is measured as a voltage. In quantum computing, the unit is the qubit, which is also assumed to be either 0 or 1 at the end of the computation. Unlike a bit, a qubit can be both 0 and 1 simultaneously, meaning they coexist during the computation. Quantum coexistence (before measurement) can be captured by a linear combination of orthogonal vectors (see, for example, R. Portugal's basic quantum algorithm). Through measurement, the quantum system is inevitably affected and produces random results, similar to a classical bit. A unitary matrix is defined if its conjugate transpose UT is also its inverse UTU = UUT = UU⁻¹ = I, where I is the identity matrix. To manipulate the state of a qubit (treating the state as the "value" of the qubit before measurement), a quantum gate is needed, where a single-qubit quantum gate can be represented, for example, as a 2×2 unitary matrix. Any matrix describing a quantum gate must be unitary because a quantum gate must be invertible and preserve the probability of amplitude. In the 1970s, Charles Bennett demonstrated how any classical computation could be converted into a reversible form (see C. Bennett's *Logical Reversibility of Computation*). This can be achieved by utilizing extra memory to store intermediate data. Consider f(x) as representing a classical computation capable of manipulating n input bits into m output bits. Simplifying, by preserving garbage g(x), every classical gate can be converted into a reversible version. Figure 113 (The figure below) illustrates the classical computation from input xi to output f(x). This method enables the construction of a reversible form from a given classical computation circuit. This reversibility makes it possible to retrieve quantum gates with desired unitary properties. The graphical representation of this method is provided by... Figure 114 Provided (see below).
[0146] According to Figure 111 (below), the system utilizing this invention can automatically retrieve, for example, the representation of a classic combined integrated circuit (EV4) from statements involving nested loops and accessing arrays (EV3). The method's perspective is to view the decomposition within a computational block as extracting the unique data bit size for each computational step, which is the minimum required for parallel computation of input bits. This is in... Figure 39 The matrix is shown and labeled "independent chains". Each row in the matrix represents the data size required to compute this step in parallel within the program. This information can be used, and the method can be made to derive quantum gates from (nested) loops. The input bit size of each template can be determined by... Export, among which, Describe the input bits (see) Figure 113 ), `dr` is the required garbage memory bits, and `dr` is the corresponding data size (e.g., 32 or 64 bits for floating-point values). This method enables the extraction of parallel computation blocks and can be used for complex cases as well. Figure 55 The implementation of the 2D heat equation is shown. EV3 is able to extract parallel computation blocks without resolving all data dependencies, and in the loop... To retrieve the number of parallel computing blocks, see [link to relevant documentation]. Figure 64 This data size information allows for the retrieval of the required number of qubits as a function of runtime parameters. and These are functions of nX and nY (the grid size, respectively). The computational basis of quantum computing is defined as... Where n is the number of qubits. This method can extract parallel combinational circuits from parallel computing blocks (…). Figure 111g Therefore, this method can derive unitary matrices (quantum gates) to compute groups of input bits, such as... Figure 114 As shown by f(x).
[0147] Figure 107 A more detailed schematic illustration is shown. Figure 106 A block diagram of embodiment variant EV2 is provided. Embodiment variant EV2 includes a process of constructing a gamma graph from computation block nodes 333 of EV1, wherein computation block nodes 333 and gamma nodes in the initial granularity consist of units in a computation matrix. Gamma nodes connected by an edge can be combined into a single gamma node in subsequent steps, as they consist of a computation segment. A computation segment is a series of CBs of the same branch node 334, without any transmissions in the transmission matrix. For example, this allows for processor architecture-specific and / or system architecture-specific optimizations to be automatically parallelized for the number of processors 2102 / 2103, the performance of different processors / cores 2102 / 2103 and / or processor units 21, the size of different memory units 22, and response time differences (especially different processor registers 2211 and / or processor caches 2212 and / or RAM units 2213). In the representation of the gamma graph, edges represent transmissions. This enables novel bounded optimization methods, such as fixing all transmissions using a hardware-defined transmission time (TT). To reconstruct the gamma nodes. When traversing the graph, if it is beneficial to compute child nodes in parallel and add transmission overhead TT, or to run all or some child nodes serially (e.g., in a multithreaded environment, TT can be seen as context switching time) without the overhead of parallelization, then the parent node can be defined by combining child nodes (which can be run in parallel).
[0148] Figure 108 The invention is illustrated in more detail by showing the application of System 1 in loop parallelization. Figure 106 A block diagram of the embodiment variant EV3. This can be illustrated along the 2D heat equation example, where the heat can be determined by accessing the array u[i+nX] in the loop body. (j nY The read / write distance obtained from the array read and write statements formed by k)] To derive the gamma diagram, the changes in loop variables i, j, and k and their dependencies on runtime variables can be obtained from the loop head / latch. Note that due to parallelization, i.e., the optimized generation of multi-core or multi-processor code (especially task scheduling), which is considered an NP-complete problem in most code, the prevailing view in the art is that optimized parallelization can only be achieved by applying heuristics. The method utilizing EV3 allows the loop section to have statements including random access data structures and loop variables, which is a non-NP-complete solution. Typically, the loop section is the most computationally intensive part of the code. The system EV3 and method of this invention allow for obtaining a simple, non-NP-complete system for the loop section. Research on the operating system of this invention demonstrates that, starting from discretized 2D heat equation (PDE) source code, optimized executable message passing interface (MPI) parallel code (send and receive principles, i.e., data dependencies must be fully resolved), where MPI is a portable message passing standard designed to run on parallel computing architectures, can be provided. Furthermore, EV3 and the method allow for a reduction in the complexity of finding the optimal solution in EV1 and EV2 by exact or heuristic methods; see [link to relevant documentation]. Figure 109b .
[0149] Figure 109a The invention is illustrated in more detail by showing the application of the system 1 of the present invention to generate gamma maps. Figure 106 The block diagram of the variant EV2 of the embodiment is shown below. This gamma diagram can describe the mixed linear integer programming problem (MLIP). The general integer linear programming (ILP) problem is defined as follows: und
[0150] in, Represents the objective function and the set of its feasible solutions. As an example, based on R. Salman's work described in "Algorithms for the Precedence Constrained Generalized Travelling Salesperson Problem," Chalmers University of Technology, Gothenburg, Sweden, 2015, the problem of optimizing gamma graphs can be formulated as a MILP problem, such as the proposed Precedence Constrained Generalized Travelling Salesperson Problem (PCGTSP). Through such a set of equations, optimization of a single unit can be obtained, or at least approximated heuristically. Extending the problem to parallel machines with m units, optimization methods can be used, such as those disclosed by R. Salman. Optimizing and Approximating Algorithms for the Single and Multiple Agent Precedence Constrained Generalized Traveling Salesman Problem (Optimization and approximation algorithms for single-agent and multi-agent priority approximation) (Broad definition of travel agent problem) "Gothenburg-Chalmers University of Technology, Sweden, 2015, Paper III F. Ekstedt et al." A Hybridized Ant Colony System Approach to the Precedence Constrained Generalized Multiple Traveling Salesman Problem (Solved using a hybrid ant colony system approach) (Regulating the problem of multiple travel agencies in a broad sense) The document, dated 2017, is explicitly incorporated herein by reference in its entirety. Specifically, referring to pages 19 and 20 (5.3a) – (5.3m), the system of equations and objective function disclosed therein can, for example, be used to generate gamma diagrams to solve the optimization problem of the computational and transport matrices under discussion. Ultimately, this directly yields the definition of the priority-constrained generalized multiple traveling salesman problem (PCGmTSP). Since the optimization steps can be performed at compile time, the computational workload covering both the general case of the code and the granularity of heterogeneous hardware can be (very) high from an application perspective.
[0151] Figure 109b This demonstrates how EV2 can be combined into EV3. Each loop portion can be compressed and approximated as a property in EV3. time of the function It can be represented as a function of the loop variable: This allows, for example, the generation of MILPs based on two different simplifications: I. Define and optimize the allocation of resources to the loop part based on the number of parallel groups in the gamma node. The amount. II. All units are used to compute loop segments, which separates the code between different loop segments and optimizes them separately, thereby reducing the overall complexity.
[0152] Figure 110 It shows a schematic illustration. Figure 106The block diagram of embodiment variant EV4 illustrates in more detail the application of the present invention system 1 in integrated circuit (IC) or chip design optimization, solving electronic engineering problems in IC design, including the logic and circuit design required for designing integrated circuits or ICs.
[0153] Figures 111a to 111h A block diagram schematically illustrates the application of the system of the present invention to IC (integrated circuit) design. The system 1 of the present invention can be applied to (see...) Figure 106 / Figure 110 Designing and optimizing VLSI designs. Circuit design is about arranging transistors to perform a specific logic function. Delays and power can be estimated from the design. Each circuit can be represented as a schematic diagram or as a netlist in text form. A brief explanation (see [link to documentation]) Figure 111a Digital logic can be divided into combinational circuits (Boolean logic) whose output depends only on the current input (a series of logic gates) and sequential circuits whose building blocks are registers (flip-flops) and latches. System 1 of the present invention can be used to determine computational block nodes. These computational block nodes can then be used to determine the digital logic, as illustrated by an example of a 2D heat equation. Figure 67 The algorithm's computation block node consists of 5 reads, 1 computation, and 1 write. Figure 111b ). Figure 111c The result of a simple circuit is shown. The read becomes a sequential circuit consisting of 5 flip-flops (which together form a register, but the effective register size is determined by the bit length of each data item). Assume that the rising edge of the clock (time k) waits for the required hold time to ensure that the correct values (logic 0 or 1) of u[k][i+1][j], u[k][i-1][j], u[k][i][j+1], u[k][i][j-1], and u[k][i][j] appear at the outputs of the flip-flops. This is essentially a read. Data can now be propagated through a combinational circuit (computation block) produced by arithmetic operations consisting of the required adders, shifters (multiplying by 4), subtractors (a combination of inverters and adders), and multipliers. At the output of the computation block, the value u[k+1] appears after the setup time (equivalent to a write operation), which is the amount of time required for the inputs of the flip-flops to stabilize before the next clock edge. The register on the right is precisely the value at the next time k+1, which is what the next iteration on the left requires. Therefore, values can be written directly into the same register. Now we can perform this thought experiment on each point in the computation matrix. For two points in the matrix ( Figure 111dIt is clear that data is now interleaved, or that only one register is needed per matrix point. Computational blocks (CBs) always consist of the same combinational circuitry, although propagation delays will never be identical in electronic implementations. Therefore, it is important to pay close attention to the critical path that limits the system's operating speed and requires attention to timing details. In VLSI design, real-world settings are always spatially constrained. Infinite parallelism is not possible, so some (not all) computational blocks are combined and processed sequentially. To enable this with a finite number of registers, a multiplexer is connected between the register outputs and the CB inputs. The multiplexer selects the output from several inputs based on a selection signal. Simultaneously, a demultiplexer is connected between the CB outputs and the register inputs (see...). Figure 111e To correctly feed back data, the design optimization process may show that demultiplexers are not always necessary. What is processed at each clock rate on an ideal parallel circuit is now handled in more realistic circuits ( Figure 111f / Figure 111g This process requires several clock cycles to process – it should be processed in parallel across multiple cycles as much as possible until a complete iteration is completed. Figure 67 Taking a 4×5 matrix as an example, this means: for 6 parallel CBs: 1 cycle to compute k+1; for 3 parallel CBSs: 2 cycles (2×3 parallel), including the higher latency due to multiplexing. VLSI designers must always make trade-offs between area, throughput, latency, power consumption, and the energy required to perform the task. The optimal circuit is always somewhere on the inverse curve (see...). Figure 111h If the available area is large, parallelization can be performed well. If the available area is small, the system must be multiplexed, which leads to higher latency. The optimal point between area and the number of parallel circuit blocks lies somewhere in between. Since System 1 of the present invention can provide optimal code for a given cell, it can also be used to find the optimal circuit for a given region, thereby helping to refine the iterative design process when the actual module size and critical path are known.
[0154] Figure 112 The diagram schematically illustrates the effect of the CB combination and its influence on... A diagram illustrating the impact. This is the size (optimized = minimized) required to compute a series of instructions on the target platform (e.g., registers). It is important to note that, due to... Depending on the instructions in CB1, CB2, and CB3, the target architecture (the available instruction set and data space characteristics, such as registers in the CPU or flip-flops / input signals in IC circuits), and the methods used for ILP optimization and scheduling, therefore . .
[0155] Figure 113 The classical computation from input xi to output f(x) is illustrated exemplarily.
[0156] Figure 114 It is shown that applying f(x) to the input bits and retaining 'garbage' values during the computation of the result of f(x) can cancel the computation of the invertible form of f(x).
[0157] Figure 115 It shows the application from statements in the code to combinational circuits and the resulting reversible forms. definition (i) "Compute block node"
[0158] The definition of the term "computation block node" is crucial to this application. A computation block node groups instructions and needs to communicate / transfer data with other computation block nodes. As used herein, the term "computation block node" differs from similar terms used in the prior art, although it does not have a universally accepted meaning.
[0159] The well-known basic block (see, for example, Proceedings of a Symposium on Compiler Optimization; July 1970, pp. 1-19, https: / / doi.org / 10.1145 / 800028.808479) is a core definition in classical control flow graphs (CFGs). In short, a basic block groups statements that have no internal jumps or jump targets. Therefore, for a given input, a basic block can execute operations uninterruptedly until the end, each leading to an output. This is a fundamental concept in modern compilers. Historically, the definition of a basic block was also focused on a single unit of computation and was quite well-developed. Optimization methods exist for various problems, and their effectiveness in addressing different technical issues has been demonstrated. However, seeing the goal of code as breaking down statements into different dependent units (e.g., via shared caches, bus connections, or network connections), the definition lacks granularity, and the classical scope hinders a broader perspective. Determining the range of a block based on any unique information given in the code (treating the information as a bit pattern) and combining that range with the relevant timing of computation and transmission of information in the system creates a different, but physically-based, perspective on the given code. Alternative ranges enable new options and resolve some well-known technical issues in today's state-of-the-art compilers (see examples of PDE, Fibonacci, or pointer disambiguation below).
[0160] The term "computation block node" as used in this application is based on a distinct and not otherwise applied critical unit in the SOTA compiler: the interrelationship between the transmission and computation time of a given group of statements. These newly defined "computation block nodes" group together instructions that use the same information, which is not altered by any other instruction (statement) in any other computation block node within a specific timeframe of the complete code. In this way, through the scope of the information (information as different bit patterns), referred to in this application as "indivisible chains of instructions," these computation block nodes group together instructions that can be processed or computed independently of any other statement. Each of these chains of instructions within a computation block node has a physically-based "time" associated with the time required for the unit to process or compute the chain of instructions on a given hardware. Because hardware properties (and software components such as the OS, drivers, etc.) have a fundamental impact on the time required to process or compute instructions, "computation block nodes" also associate them with the time required to transmit any other information (if needed in a particular program step) to another "computation block node" in the complete code within a specific timeframe. Each "computation block node" knows which information of its own instructions must be exchanged (communicated / transmitted, referred to as "received" or "sent") to other "computation block nodes" and when such information must be exchanged (communicated / transmitted, referred to as "received" or "sent") to other "computation block nodes." Therefore, the "computation block nodes" used in this application introduce new scope and decision criteria, which pertain to a core aspect of code parallelism involving either computing information (bit patterns) on a unit or transferring this information to another unit for parallel computation. This decision can only be made if it is guaranteed that the information used in any other part of the program will not change during a particular program step (or time). Furthermore, constructing block nodes with this scope not only provides advantages for parallelizing a given code, but this scope also shows some advantages for problems that cannot be well handled using SOTA compiler optimization techniques. Such problems and different solutions are discussed in, for example, in D. Grune's publications. Modern compiler design (Modern compiler design) There are excellent records of these techniques. To demonstrate the technical advantages, the following shows some of the advantages of using the new range to solve some of these known technical problems, such as the different performance of pointer disambiguation and Fibonacci sequence code, and how this method solves problems that have been unsolvable until now, such as PDE parallelization.
[0161] first, Figure 6Different ranges are illustrated through schematic examples. The illustration has been adjusted to more easily demonstrate the operation of the system and method of the invention; for example, the statement 'y>a' will not appear twice in the same computation chain, and the resulting "computation" -> "communication" model will lead to the corresponding placement of loops, jumps, or flow control instructions. Nevertheless, this example illustrates the different ranges given by computation block nodes compared to the basic block: in fact, 'a' and 'b' do not change in block 1, and the evaluation statement 'y:=a'... After b', information about the condition 'y>a' is already known, and the alternative range of the computation block node takes these properties into account. The proposed computation block node perspective groups statements together in a new way. This change in perspective stems from the method of grouping operations together, which relies on information that does not change at the same time step in the code. The example illustrates the evolution of two independent computation chains, both independent of the information for 'y'.
[0162] exist Figure 7 In a simplified but more realistic example, the method of the present invention takes advantage of the fact that logarithmic instructions (FYL2X as an example on modern CPUs) require much longer instructions than floating-point addition and / or multiplication instructions (e.g., FADD, FMUL). The method of the present invention translates the statements 'x:=a+b' and 'y:=a...' into... b' is added to two different computational block nodes (cbn) because both are based on the same information 'a' and 'b'. Since the statement 'log2(x)' uses information 'x', it is appended to 'x=a+b'. Information 'y' is being transmitted, so this information can be used in two independent computational chains. (ii) "Computation Matrix" and "Transmission Matrix"
[0163] The method of this invention forms two technically defined matrices from the flowchart of the computation block nodes described above, referred to herein as " Calculate matrix "and" Transmission Matrix " Both are numerical matrices. “ Calculate matrix "Includes a chain of instructions, while" Transmission Matrix This includes possible transport properties (possible transport properties from other compute block nodes and possible transport properties to other compute block nodes). Therefore, the code extracted from the matrix always forms a "compute -> communicate" pattern, as described in more detail in the following paragraphs. If the code is mapped to a single cell, the communication portion disappears, and the method of this invention is simplified to a method utilizing basic blocks, which can be processed individually using the SOTA compiler. See also Figure 7In this example, we can see that unit 2 can compute the long execution instruction of the statement 'log2(y)', and unit 1 processes the loop and increments a ('a=a+1'). See [link to example]. Figure 8 To understand how it works, the matrix builder will be shown in detail in the next paragraph.
[0164] The name "matrix" is used to name structures of the form (m x n x p), where m, n, and p are... Since m, n, and p depend on the code, this can include different forms of mathematical objects, especially those involving dimensions such as points, vectors, matrices, and tensors. m is the maximum number of computation blocks, and n is the block number, such as... Figure 43 In the segment number, n is the number of independent compute block nodes with the same segment number, such as... Figure 43 The chain number is represented in the code. Based on the highest condition level (or a series of branch nodes, such as...) in the code... Figure 26 As shown in the diagram, p is defined as follows: Figure 43 The path number is represented in the text. Therefore, it can be said that whenever the term "matrix / multiple matrices" is used, it can be a vector, matrix, tensor, or any other object with a form (mxnxp), or represented as a graph or tree. Thus, in code with only one block / segment number, optimization can also be done, for example, using a tensor by combining the computation and transfer matrices into a structure, or the transfer and computation matrices can each be tensors, or both can be vectors. The dimensions of these "matrices" depend on the form of the code and the way information is processed / represented in relation to the application of the method. The term "numerical matrix" used in this paper can also include textual forms, such as the transfer '1->2'. Depending on the optimization / mapping technique used, the text in the matrix will be or can be simplified to numerical values (depending on the character encoding used) so that it can be searched or compared, for example. Alternatively, the text transfer '1->2' can be represented / encoded numerically from scratch and directly compared with other transfers, thus omitting character encoding.
[0165] Since a numerical matrix can be used as another well-formatted form to represent a graph / tree structure, all optimizations / mappings can also be performed in a graph / tree format instead of a numerical matrix. Regardless of the mathematical or computational form used to represent the instruction group (here referred to as a computational block node) and its transmission dynamics (here exemplified by...), Figure 23The "transmission packet" mentioned above refers to the physical dependencies of transmission and computation delays that occur in all binary-based electronic computing systems. It is based on grouping instructions (any form of instruction / operation, such as those representing electronic circuits) within code (any form of code, such as high-level, assembly, etc.), with the rule being that instructions that "read" information A are placed in the same group (here called computation block nodes) as instructions that "write" information A. This differs significantly from grouping instructions using well-known basic blocks. If dependencies are not explicit (e.g., ...), Figure 21 As shown, in a case where each instruction in a graphics element has two "read" nodes and one "write" node, a "transfer" is introduced between two computational block nodes (one holding the "write" instruction and one holding the "read" instruction). In this form, the code can be represented as computational block nodes connected by the required transfers. This information can be contained in a graph / tree, an array, or any suitable structure. To run these instructions on a given hardware, known methods in SOTA compilers can, but are not required, be used to optimize the chain of computational block nodes grouped into instructions, and then run each unit on the computational unit involved (in this case, called transpiling). (iii) The Path of "Matrix Builder" and Regression Code
[0166] After parsing the code and adding all instructions to the compute block nodes (CBNs), each compute block node can be enumerated based on its position in the flow graph. This produces a control flow graph of a similar form, given by the edges between CBNs and the connections between defined branch nodes. Using these location numbers, a unique position in the code flow is used to place information about what to compute and what to transmit in two matrices. Calculate matrix "and" Transmission Matrix "middle," Calculate matrix "Used for calculations, while" Transmission Matrix "Used for transmission. Obviously, metadata can be easily derived, such as the data size required for each CBN, the size of transmissions between CBNs, etc."
[0167] Matrix representations offer a more scalable form of information access than graphs, demonstrating the good formability of control flow graphs. They are not absolutely necessary for this method, and the step can also be performed directly on a graph / tree structure. However, the definition of block nodes also indicates the general nature of the matrix of this invention: each row has an independent instruction flow (through transport dependencies) (= computation) and the required transports (= communication) to other CBNs. This guarantees: a) no further information is needed to compute all instructions in the computation block node (similar to basic blocks, but with a completely different scope of independence), b) the information used does not change anywhere else during the same computation step throughout the code, and c) only information unaffected by computation during this time step is transported. Based on this fact, each cell in the computation matrix has all instructions that can be computed simultaneously and independently with all instructions in other cells in the same column. In the transport matrix of each cell, the transports required at the start and end of each computation step (the corresponding cell in the computation matrix) are now known. Obtaining code running on different cells produces a representation in the form of "communication -> computation -> communication -> computation," etc. Each row represents a chain of computation and communication attributes, forming a series of computations coupled through communication with other rows = computation chains. The information required for communication with other rows = the chain is located in the transfer matrix. Each row in the computation matrix (and the same combination in the transfer matrix) can also be combined with any other row in the matrix (computing all instructions of the two combined units and making the necessary transfers to the two units based on the transfer matrix) to create new combinations of computation <-> transfer behaviors for a given code. In this step, the computations are added, and the transfers on the same unit (through combination) disappear. This will later lead to a simpler form of optimization, and the fact that the optimization / mapping step will definitely produce runnable code because no iterative or similar workaround is needed. This is also a well-known problem with parallelized code, because debugging parallel code is very complex (see, for example, A. Danner et al.'s "..."). ParaVis: A Library for Visualizing and Debugging Parallel Applications (ParaVis: a library for visualizing and debugging parallel applications) (”).
[0168] As defined in this paper, each row of the computation matrix represents a unit's instruction chain. The unit depends on the implementation level (e.g., raw assembly, thread, process, compute node, etc.). Clearly, empty blocks (empty units in the computation matrix) or unused communication entries (empty units or transmissions on the same unit in the transmission matrix) disappear, and the start and end communications are linked together, as shown below. Figure 10 As shown. If the code runs on a single unit, it will result in no transfers, and all transfers will be lost by reallocating / renaming variables, applying well-known optimization methods in the SOTA compiler to obtain optimized code for a given unit.
[0169] Depending on the method of communication implementation, non-blocking or blocking mechanisms can be used, as it is guaranteed that no information will be transferred to another CBN with the same number during the computation of a block node. Depending on the level, the computation and communication parts can be implemented, allowing the method to be used as a compiler or transpiler. The method of transferring code back to a "computation -> communication" form also allows for the use of the language best suited to the application (e.g., C, C++). ++ It becomes easy to use Python, and depending on the target infrastructure, it makes it easy to use methods such as IPC (Inter-Process Communication) methods (e.g., queues / pipes, shared memory, MPI (Message Passing Interface)), libraries (e.g., event libraries, multiprocessing libraries), and the use of available state-of-the-art compilers. (iv) "Optimization"
[0170] The general, well-defined nature of matrices is the unique foundation for the extensive possibilities of mapping / optimizing code to a given hardware or evaluating the optimal hardware configuration for a given code (see, for example, [link to relevant documentation]). Figure 106 Different implementation variations (E1-E5) are described. Therefore, this structure guarantees executable code. Each hardware infrastructure has its own performance properties, and combined with the available software layers, modern ICT (Information and Communication Technology) infrastructure is highly complex. The method of this invention allows code to be optimized for hardware or allows for the provision of ideal hardware. This is most evident in constructing different row combinations from the computation and transmission matrices, where it is important to construct the same combinations in both matrices. Each combination (e.g., combining the first and second rows of the computation and transmission matrices) is a new version of parallel / concurrent code for a given input code, whose properties on the target infrastructure can then be evaluated, see [see...]. Figure 11 A simple example.
[0171] Different combinations of computation <-> communication ratios are retrieved by combining rows in the matrix (e.g., combining rows 1 and 2 or rows 2 and 5 in the computation and communication matrix). Each combination can then be examined, including other known metadata about the given hardware / software infrastructure. For example, the data type of a data node can be used to evaluate hardware attributes such as cache length, available memory, or other attributes of the target platform. This combination and search for the optimal computation / communication ratio for a given code and given hardware always produces runnable concurrent code because iterative solutions or similar methods are not required in the optimization steps to find a solution, and solutions with, for example, race conditions, deadlocks, etc., are not encountered, and deadlocks can be detected separately.
[0172] Instruction grouping is based on the inherent physical constraint that transport is typically an order of magnitude larger than computation at the same "location." This method generates the optimal solution space for the most easily divisible code form and produces a well-defined search space for finding the best mapping for a given hardware or the ideal hardware for a given code. This makes the method highly general and solves the technical problem of automatically adapting given code to a target platform. If this method is used as a transpiler, the code can be optimized to the target hardware / unit using a state-of-the-art compiler.
[0173] Other methods do not utilize the inherent temporal properties and dependencies given in the code, nor do they generate a unique solution space of this form for optimization. The method in this application, which defines computational block nodes in the form of grouping by ranges of invariant information, directly addresses the technical problem in many ways. Examples in the detailed description will illustrate this in more detail. (v) The "computational block node" according to the present invention and the "basic block or slice" of the prior art
[0174] Compute block nodes differ from basic blocks or slices in that they have a different scope. They connect independent parts of the program, for example, based on their jumps / branches, and do not follow the definition of basic blocks. The instruction chains in a compute block node have basic data dependencies, meaning that the information used in these chains will not change anywhere else in a given code and will not be transferred at the same time / program step.
[0175] Therefore, time and the location of instructions within a program are dependent on computation block nodes. Computation block nodes consist of chains of instructions based on the same information, whereby information is defined as bit patterns in each form (e.g., data variables, pointer addresses, etc.). By introducing transport / communication, where information is used not only by time steps in the code but also coupled with instructions, this physical-time correlation is achieved within the computation block node. This approach positions computation blocks in such a way that it determines at all points in time which information can be transported and where, and which information can be computed in parallel. This provides a different perspective, especially for optimization techniques. A wide range of technical problems exist that can be addressed through this shift in perspective. Computation block nodes link the location of information (bit patterns) within the computational framework to the timing of that information's use within the program. This is supported by the fundamental physical principles of computation in classical infrastructure. The following example with nested loops and arrays nicely illustrates this effect: when distributed across parallel computation block nodes, branches in a loop definition can be transformed into reads and writes to data points based on an array.
[0176] The method of this invention segments code into multiple computational segments, and the resulting information must be transferred to these segments. Therefore, by defining computational block nodes, the method generates a matrix system where given instructions are grouped based on the same information, and the constraint is that the same information is not needed elsewhere in the infrastructure at any given point in time. Grouped instructions cannot be further subdivided because it is impossible to compute a particular group of instructions faster, as any form of transfer would be longer than computing that given chain within a computational block node. As shown, the general nature of the computation and transfer matrices allows for the optimization of segmented code into the most concurrent possible solution for a given hardware. The ratio of computation to transfer depends on the target hardware, and the method provides different solutions for splitting code at different ratios for a given code. By converting the dependency graph into matrices, these matrices can be used more effectively to map / optimize the segmented code to the target platform, including the specific properties of this infrastructure (e.g., GPUs require a different transfer / computation distribution compared to CPUs). However, using matrices is not mandatory; optimization / mapping can be done directly on the graph / tree structure. (vi) "Idle Time" - "Delay Time"
[0177] The latency defined herein refers to the idle time between processing unit 21 sending data back to parallel processing system 2 after processing a specific instruction block of processing code 32 for data, and receiving the data required for the same processing unit 21 to execute consecutive instruction blocks of processing code 32 (i.e., after retrieving and / or retrieving data). Conversely, the idle time of a processing unit can be defined herein as the amount of time a processing unit is not busy between two computation block nodes, or the amount of time a processing unit executes idle processes of the system. Thus, idle time allows for the measurement of the unused capacity of processing units in a parallel processing system. Maximum speedup, efficiency, and throughput are ideal for parallel processing, but are unattainable in practice because speedup is limited by various factors that cause idle time in processing units. The idle time of processing units used herein can be attributed to various reasons, including in particular: (A) Data dependencies between consecutive computation block nodes (i.e., tasks that cannot be further structurally decomposed through read / write operations): There may be dependencies between instructions on two computational block nodes. For example, an instruction cannot start until the previous instruction returns a result because the two instructions are interdependent. Another instance of data dependency is when two instructions attempt to modify the same data object, which is also known as data risk; (B) Capital Source constraintsWhen resources are unavailable during execution, latency occurs in the pipeline. For example, if a shared memory is used for both data and instructions, and simultaneous reading / writing and instruction fetching are required, only one can be executed, while the other must wait. Another example is resource-constrained resources, such as execution units, which may be busy when needed; (C) Branch instructions in the program and Interruption The program is not a linear flow of sequential instructions. Branch instructions may alter the normal flow of the program, delaying execution and impacting performance. Similarly, interrupts may postpone the execution of the next instruction until the interrupt is handled. Branches and interrupts can negatively impact minimizing idle time.
[0178] Please note that the task of minimizing idle time is sometimes also called "load balancing," which means distributing work among processing units so that, ideally, all processing units are always busy. (vii) "Basic Commands"
[0179] As used herein, the terms "basic operation" or "basic instruction" refer to machine operations that do not contain simpler operations. They reside at the machine language level. However, in certain embodiment variations, they may include at least microcode instructions or consist entirely of microcode instructions. Since microcode is the result of low-level machine language interpretation, microcode instructions directly manage hardware resources at the register or circuit level. Machine language interprets machine instructions and sends them to the lowest hardware level, where they are translated into small microprograms called microcode. Therefore, microcode is low-level code that defines how a microprocessor should behave when executing machine language instructions. Typically, one machine language instruction is translated into several microcode instructions.
[0180] As described above, the execution of basic instructions (as defined above) typically involves the sequential execution of several operations, including operations such as resetting registers, resetting memory storage, shifting characters in registers left or right by one bit, transferring data between registers, and comparing data items and performing logical addition and multiplication. Groups of basic operations can provide a structure for executing specific instructions. Basic operations include the basic logical functions of logic gates, including AND, OR, XOR, NOT, NAND, NOR, and XNOR. It can be assumed that these basic operations take a constant amount of time on a given processing unit and may only change by a constant factor when running on different processing units 21 or parallel processing systems 2.
[0181] Based on the concept of microcode instructions, the design of integrated circuits, such as Field-Programmable Gate Arrays (FPGAs) and Application-Specific Integrated Circuits (ASICs), involves several levels of abstraction, ranging from high-level algorithmic descriptions to low-level hardware descriptions. These descriptions are either written in Hardware Description Languages (HDLs), which allow designers to define the functionality and behavior of their circuits at a very low level, or increasingly utilize High-Level Synthesis (HLS) processes to describe the behavior of digital systems using high-level languages such as C or C++. Logic synthesis tools, similar to compilers for hardware, map HDL code onto a library of gates called standard cells to minimize area while satisfying some timing constraints. This generates a Register Transfer Level (RTL) description of the system, which defines how data flows between registers and how computations are performed using Arithmetic Logic Units (ALUs) or even just logic gates that implement Boolean functions or arithmetic. The RTL description is then synthesized onto gates and flip-flops to generate a Gate-Level Synthesis (GLS) netlist. The netlist is the lowest level of abstraction, representing the actual hardware implementation of the digital system.
[0182] Because computation block nodes group these basic logical operations, the logic gate layout can be derived from them, as each computation block node consists of basic gates (such as NOT, AND, OR, XOR, NAND, NOR, and XNOR) or more complex gates (such as multiplexers, decoders, adders, subtractors, shifters, multipliers, and dividers). Since computation block nodes are already a series of basic operations, they can also be viewed as sequences of Boolean functions and / or arithmetic.
[0183] In the first step, described in more detail below, the system of the present invention converts source code into a sequence or code 32 of basic operations 321, ..., 325 constructed from loops, branches, and sequences. It is platform- and compiler optimization-level independent, and therefore the same conversion can be used to optimize execution time on any platform.
[0184] This method is based on decomposing 31 segments of source code written in a programming language into basic operations 32 / 321, ..., 325, i.e., different transformed portions of source code 31. The set of basic operations is finite for each processing unit and has several subsets: integer, floating-point, logical, and memory operations. These sets are related to various parts of the processor architecture and memory data paths. The basic operations used in this paper can be classified, for example, into the following levels: The top level contains four operation classes: integer, floating-point, logical, and memory. The second level of classification can be based on the source of the operands (i.e., their location in memory space): local, global, or procedural parameters. Each group can exhibit different timing behaviors: local variables are used extensively and are almost always cached, while global and parameter operands must be loaded from arbitrary addresses and may result in cache misses. The third level of classification is by operand type: (1) scalar variables, and (2) one-dimensional or multi-dimensional arrays. A pointer is considered a scalar variable when its value is given using a single variable; a pointer is considered an array when its value is given using multiple variables. Operations belonging to the integer and floating-point classes are: addition (ADD), multiplication (MUL), and division (DIV). The logic class includes: logical operations (LOG, i.e., AND, OR, XOR, and NOT); and shift operations (SHIFT): performing bitwise shifts (e.g., rotation, transposition, etc.). Memory-related operations are: single memory allocation (ASSIGN), block transactions (BLOCK), and program calls (PROC). A MEMORY BLOCK represents a transaction of size 1000 and can only have array operands. A MEMORY PROC represents a function call with one parameter and a return value. The parameter can be a variable or an array, declared locally or given as an argument to the calling function, but cannot be global. (viii) "Processor" – "Core"
[0185] In order to use the term " nuclear The term "multi-core processor" must be defined, for example, as used in this article, and the term "multi-core processor" must also be given. deal with instrument "(or" microprocessorThe definition of a processor. In computing terminology, a processor is a component that reads and executes program instructions. A processor core is a processor, that is, an individual processing unit within a computer's central processing unit (CPU). Instructions to the processor are technical signals given to the processor / core 2102 / 2103, telling the processor / core 2102 / 2103 what to do, such as reading data from memory or sending data to the output bus. The most common type of processor is the central processing unit (CPU). A multi-core processor is generally defined as an integrated circuit with two or more independent processors (called cores) attached. Note that this term is different from but related to the term multi-CPU, which refers to an integrated circuit with multiple cores not attached to the same memory core. A CPU is an integrated circuit. In the prior art, the term single-processor generally refers to a system having one processor [single processor], and that processor has one core. This term is used in contrast to multiprocessor architectures (i.e., multi-core, multi-CPU, or both). Multi-core processors evolved from single-processor technology, becoming a method in the computing industry to achieve higher performance through parallelism rather than raw clock speed. For many years, the computer industry developed increasingly faster single processors, but this pursuit was nearing its end due to limitations in transistor miniaturization, power requirements, and heat dissipation. As the clock frequency of single-threaded cores reached a stable level, chip manufacturers turned to multi-core processors to utilize parallelism to enhance performance. (ix) Parallelization types and performance in multi-core CPUs
[0186] Since multi-core CPUs fundamentally rely on parallelism to enhance performance, understanding the main types of parallelism is crucial for analyzing performance and comprehending the technical issues associated with automatically parallelized systems. A modern multi-core processor without code parallelization is meaningless. However, parallelism is a technically challenging and complex subject; however, in the context of this invention, understanding the three basic types of parallelism presented here is sufficient. Instruction-level parallelism, thread-level parallelism, and data-level parallelism are all employed in various multi-core CPU architectures and have different impacts on performance; understanding these impacts is essential for thorough performance analysis.
[0187] Instruction-level parallelism (ILP) This is the first type of parallelism, which involves executing certain instructions of a program concurrently, instructions that would otherwise be executed sequentially. This can have a positive impact on performance, depending on the combination of instructions in the application. In the prior art, many CPUs utilize instruction-level parallelism techniques, such as pipelining, superscalar execution, prediction, out-of-order execution, dynamic branch prediction, or address speculation. However, only certain portions of a program's instruction set may be suitable for instruction-level parallelism, as illustrated in the examples in Table 2 below.
[0188] Because steps 1 and 2 of a sequential operation are independent of each other, a processor employing instruction-level parallelization can execute instructions 1.A. and 1.B. simultaneously, reducing the number of operation cycles required to complete the operation by 33%. However, in either case, the final step must be executed sequentially, as it depends on the first two steps. Clearly, this example is overly simplistic. However, for automatically parallelized systems, the key is to identify which parts of the application have instructions that can be executed in parallel.
[0189] Thread-level (or task-level) parallelization (TLP) This is the second type of parallelization, involving individual threads that execute tasks delegated to the CPU simultaneously. Thread-level parallelization can significantly impact the performance of multithreaded applications through a variety of factors, from hardware-specific and thread-implementation-specific to application-specific, making a basic understanding of this type of parallelization crucial. Each thread maintains its own memory stack and instructions, and can therefore be treated as an independent task, even though threads may not actually be truly independent within a program or operating system. Thread-level parallelization is used by programs and operating systems with multithreaded designs. Conceptually, it's intuitive to see why thread-level parallelization can improve performance. If threads are truly independent, distributing groups of threads across the available cores on the processor reduces the used execution time to the maximum execution time of any single thread, compared to a single-threaded version that requires the additional execution time of all threads. Ideally, the work is also evenly distributed among the threads, minimizing the overhead of allocating and scheduling threads. In the real world, this ideal model of thread-level parallelization performance is complicated by several technical factors, so ideal situations are rarely seen in practical applications. Factors affecting performance include load balancing, the level of execution independence, thread locking mechanisms, scheduling methods, and the required thread memory. Furthermore, data-level parallelism among distributed threads can impact performance. The thread implementation libraries in both the operating system and specific applications can also affect performance.
[0190] Data-level parallelization (DLP) This is the third type of parallelization, involving sharing common data among executing processes through memory consistency, improving performance by reducing the time required to load and access memory. Typically, identifying application areas that leverage data-level parallelization will help in understanding the performance characteristics of multi-core processors.
[0191] Loop-level parallelization (LLP) This is the fourth type of parallelization, where iterations of loops execute in parallel if they have no dependencies. If all loop iterations require the same execution time, allocation can be performed using static allocation, where the number of iterations allocated to each computational unit is fixed.
[0192] In the context of multi-core CPUs, data-level parallelization in core-shared cache memory can have a significant impact on performance. Here, the execution process running on multiple cores is called a thread. Performance can be improved when threads read the same data from shared memory. This allows multiple threads to use a copy of the data, reducing the number of copy operations and thus reducing execution time. When threads do not share common data, each thread must maintain its own copy of the data and receives no benefit. However, if multiple requests for that memory exceed its bandwidth, adding more threads can negatively impact performance. Further performance impacts can occur during write operations. Multiple threads attempting to write to the same memory location simultaneously must wait to resolve conflicts. To address this, schemes are needed to handle this situation, such as spin-locks. The performance impact depends on the penalties involved in the scheme employed and the frequency of such conflicts. Generally, allowing multiple threads to write to different regions of shared memory is preferred in terms of reducing the likelihood of triggering these penalties. Non-uniform memory architecture (NUMA) can help because it places data used by a particular core in memory physically closer to that core. Furthermore, bandwidth becomes a significant factor as the number of threads increases on multi-core processors. Limited cache size (cache misses), limited bandwidth, out-of-cache latency, and other factors all impact performance, although data-level parallelism can improve performance in some cases. Moreover, the interaction between instruction-level parallelism and data-level parallelism affects performance. Flynn's taxonomy provides a technical framework for analyzing these interactions. In conclusion, observing data-level parallelism in a specific application is crucial for analyzing its performance on multi-core CPUs, as memory is often a limiting factor. (x) Fully automated parallelization metrics for P and NP
[0193] In the fields of computer technology, code parallelization, and processor architecture, there are numerous systems and methods addressing the technical challenges of improving the computational speed and memory footprint of code and algorithms. This is because faster algorithms can provide additional time for more computations, while less memory usage can further enhance computation, especially in parallel computing. As mentioned above, the time spent on a computer computation problem is called the "time taken to solve it." Time complexity The space occupied is called "". Space complexity The time and space required to execute these algorithms are typically measured in terms of the size of the input and the number of elements the algorithm must operate on. There exists another metric related to these two: the so-called "..." computational complexity "Computational problems" is a metric that categorizes computational problems based on their resource usage and associates these categories. Computational problems are tasks that are solved by computers and their processors. Computational problems are technical problems that can be solved by mechanically applying processing steps through data processing devices (e.g., processors and data repositories).
[0194] If solving a computational problem requires significant resources, then the problem is considered inherently difficult, regardless of the processing steps or algorithms used. To provide a metric, computational models are used, among others, to quantify computational complexity—that is, the amount of resources required to solve a problem, such as time and storage. Other complexity metrics are also used, such as communication volume (used for "..."). Communication complexity "), the number of gates in the circuit (used for " circuit complexity ") and the number of processors (for parallel computing).
[0195] One function of computational complexity is to provide a metric for measuring the practical limitations of computing or parallelization. On the other hand, if a computational problem is considered easily solvable, it means that the problem can be solved quickly using computing devices (here, automatic parallelization). The term "computational complexity" used above... fast "P" refers to the existence of processing code or algorithms that solve the task in polynomial time, meaning the time to complete the task varies as a polynomial function of the size of the algorithm's input (rather than exponential time). For a class of problems, some algorithms can provide solutions in polynomial time; these problems are called "P" problems for polynomials. Therefore, parallelization problems belong to class "P," where the time to find a solution (i.e., parallelized code) is within the range of n (e.g., n...). 1 n 2 or n 99 In the case of parallelization problems, where n is promoted to an exponent, the time and space polynomials increase exponentially. On the other hand, for a class of parallelization problems, the time to provide a solution grows exponentially (i.e., not in polynomial time), these problems are called "NP" (nondeterministic polynomial time). Unlike parallelization problems in P, NP parallelization problems are parallelization problems that require extremely long time and space for computers to solve; the time grows exponentially with the number of elements in the input. This exponential time is described as any number raised to the power of n, such as 2^n. N .
[0196] In this paper, it is noted that for some problems, there is no known fast way to find a solution, but if information indicating what the answer is is provided, it is possible to quickly verify the answer. In terms of computational complexity metrics, such a technical problem is called NP-complete (“nondeterministic polynomial-time complete”), where “nondeterministic” refers to a nondeterministic Turing machine, “complete” refers to the property of being able to simulate everything in the same complexity class, and “polynomial-time” refers to the amount of time considered “fast” for a deterministic method to check a single solution or for a nondeterministic Turing machine to perform the entire search. This means that a computational problem is NP-complete if (i) for a technical problem, the correctness of each solution can be verified quickly (i.e., in polynomial time) and a solution can be found using brute-force search by trying all possible solutions; and (ii) the computational problem can be used to simulate all other problems whose solutions can be quickly verified. In this sense, NP-complete problems are the hardest problems whose solutions can be quickly verified. If a system or algorithm can quickly find a solution to a certain NP-complete problem, then the system or algorithm can quickly find solutions to all other problems whose solutions can be easily verified. In computational techniques, this problem is referred to here as “NP-complete”. P and NP problems The question asks whether a problem that can be verified in polynomial time can also be solved in polynomial time. This question has profound technical implications, particularly for code parallelization and the power of systems or methods used for parallelization. Specifically, if a parallelization system and / or method can provide parallelization of a certain code or code structure that is an NP-complete problem, then all other similar NP-complete codes and code structures can be parallelized to the same extent using that parallelization system or method, except for polynomial-time reduction. Clearly, for code parallelization, brute force can, in principle, always be used to search for optimal parallelization by generating and testing all possible permutations of all possible basic blocks or computational block nodes or tasks or threads, including all possible permutations of parallel instructions. However, using brute force search, the complexity of code parallelization typically grows exponentially, resulting in a failure to scale to the computational power of the applied computing device. Some existing technical solutions attempt branching and delimiting by taking different choices or assuming different tasks or threads. But coordinating tasks / threads becomes more difficult, and technically, deriving and / or verifying optimally optimized parallel code becomes challenging. Detailed Implementation
[0197] Figure 12 and 13The architecture of a possible implementation of an embodiment of compiler system 1 is schematically illustrated for optimizing the compilation of program code 3 for execution by a parallel processing system 2 having multiple processing units 21. It is important to note that in this document, when an element is referred to as "connected to" or "coupled to" another element, it can be directly connected to or coupled to that other element, or there may be intermediate elements. Conversely, when an element is referred to as "directly connected to" or "directly coupled to" another element, there are no intermediate elements. Furthermore, certain portions of the following detailed description are presented in the form of other symbolic representations of programs, logic blocks, processes, and data bit operations in computer memory. These descriptions and representations are means used by those skilled in the art of data processing to most effectively communicate their work to others skilled in the art. In this application, programs, methods, logic blocks, processes, etc., are considered as self-consistent steps or sequences of instructions that produce the desired result. The embodiment variations described herein can be discussed in the general context of processor-executable instructions residing on some form of non-transitory processor-readable medium, such as program code or blocks of code executed by one or more processors or other devices. Generally, program code includes routines, programs, objects, components, data structures, etc., that perform specific tasks or implement specific abstract data types. The functionality of program code can be combined or distributed as needed in various embodiments. The techniques described herein can be implemented in hardware, software, firmware, or any combination thereof, unless specifically described as implemented in a particular manner. Any feature described as a module or component can also be implemented together in an integrated logic device or separately as a discrete but interoperable logic device. If implemented in software, these techniques can be implemented at least in part through a non-transitory processor-readable storage medium comprising instructions that, when executed, perform one or more of the methods described above. The non-transitory processor-readable data storage medium can form part of a computer program product. For firmware or software implementations, these methods can be implemented by modules (e.g., programs, functions, etc.) having instructions that perform the functions described herein. Any machine-readable medium that tangibly embodies the instructions can be used to implement the methods described herein. For example, software code can be stored in memory and executed by one or more processors. Memory can be implemented within the processor as, for example, registers, or externally to the processor.
[0198] The various exemplary logic blocks, modules, circuits, and instructions described in conjunction with the embodiments disclosed herein can be executed by one or more processors or processor units 21, such as one or more central processing units (CPUs) 210 (e.g., including a control unit 2101, a processor 2102 having registers 21021 and combinational logic 21022), and / or graphics processing units (GPUs) 211, and / or sound chips 212 and / or vision processing units (VPUs) 213, and / or tensor processing units. (TPU) 214 and / or Neural Processing Unit (NPU) 215, and / or Physical Processing Unit (PPU) 216, and / or Digital Signal Processor (DSP) 217, and / or Co-processing Unit (SPU) 218 and / or Field Programmable Gate Array (FPGA) 219, or any other processor unit 21 known in the art, such as a Motion Processing Unit (MPU) and / or a general-purpose microprocessor and / or Application-Specific Integrated Circuit (ASIC) and / or Application-Specific Instruction Set Processor (ASIP), or other equivalent integrated or discrete logic circuitry. The term “processor” or “processor unit” 21 as used herein may refer to any of the above-described structures or any other structure suitable for implementing the techniques described herein. Furthermore, in some respects, the functions described herein may be provided in dedicated software or hardware modules configured as described herein. Moreover, these techniques may be implemented entirely in one or more circuit or logic elements. The general-purpose processor 21 may be a microprocessor, but alternatively, the processor may be any conventional processor, controller, microcontroller, or state machine. In the described embodiments, processing elements refer to a plurality of processors 21 and associated resources (e.g., memory or memory units 22). Some of the example methods and apparatuses disclosed herein can be implemented in whole or in part to facilitate or support one or more operations or techniques for processing code in a plurality of processors. The multiprocessing system 2 may also include a processor array comprising a plurality of processors 21. Each processor 21 of the processor array may be implemented in hardware or a combination of hardware and software. The processor array may represent one or more circuits capable of performing at least some information computing techniques or processing. By way of example, but not limitation, each processor of the processing array may include one or more processors, controllers, microprocessors, microcontrollers, application-specific integrated circuits, digital signal processors, programmable logic devices, field-programmable gate arrays, etc., or any combination thereof. As described above, the processor 21 may be any general-purpose central processing unit (CPU) or dedicated processor, such as a graphics processing unit (GPU), a digital signal processor (DSP), a video processor, or any other dedicated processor.
[0199] This invention includes a compiler system 1 having subsystems 11, ..., 16. In a non-limiting embodiment, the subsystems include at least a lexical analyzer / parser 11 and / or an analyzer 12 and / or a scheduler 13 and / or a matrix module 14 and / or an optimizer module and / or a code generator 16. Furthermore, they may also include a processor array and / or memory. The compiler 1 segments code into multiple code blocks. In the embodiments described, a block or code block refers to a segment or portion of code grouped together. Grouping allows groups of statements / instructions to be treated as if they were a single statement and limits the scope of variables, procedures, and functions declared within a block so that they do not conflict with variables of the same name used elsewhere in the program for different purposes.
[0200] The memory or memory unit 22 of the parallel processing system 2 may include any memory for storing code blocks and data. Memory 22 may represent any suitable or desired information storage medium. Memory may be coupled to processor unit 21 and / or processing array. As used herein, the term "memory" 2 refers to any type of long-term, short-term, volatile, non-volatile, or other memory, and is not limited to any particular type or number of memories, or the type of medium storing the memory. Memory 2 may, for example, include main memory unit 211 as processor register 2111 and / or processor cache 2112, which includes multi-level caches such as L1 cache 21221, L2 cache 21222, etc., and / or random access memory (RAM) unit 2113. Regarding this application, it must be noted that the problem with multi-level caching is the trade-off between cache latency and hit rate. Larger caches have better hit rates but longer latency. To resolve this trade-off, multi-level caching can be used, in which small, fast caches are backed up by larger, slower caches. Multilevel caching typically operates by first checking the fastest L1 (Level 1) cache. If a hit occurs, the processor can proceed at a higher speed. If a smaller cache miss occurs, the next fastest cache (L2, Level 2) is checked, and so on, before accessing external memory. Cache access is not directly controlled by the programmer. It can be affected by data locality and / or compiler hints. Along with main memory and the fastest cache (see...),... Figure 1The latency differences between processors are becoming increasingly large, and some processors have begun to use up to three levels of on-chip cache. Memory 2 may also include, for example, auxiliary storage units 212 and / or third storage units 213 (e.g., tape backup, etc.), with auxiliary storage units 212 including, for example, hard disk drives (HDDs) 2121 and / or solid-state drives (SSDs) 2122 and / or universal serial bus (USB) memory 2123 and / or flash memory drives 2124 and / or optical storage devices (CD or DVD drives) 2125 and / or floppy disk drives (FDDs) 2126 and / or RAM disks 2127 and / or magnetic tapes 2128, etc. In at least some implementations, one or more portions of the storage medium described herein may store signals representing information expressed by a particular state of the storage medium. For example, an electronic signal representing information can be "stored" in that portion of the storage medium by influencing or changing the state of a portion of the storage medium (e.g., memory, registers, flip-flops, etc.). Thus, in a particular implementation, such a change in state of the portion of the storage medium storing signals representing information constitutes a transition of the storage medium to a different state or thing. As described above, memory 2 may include, for example, random access memory (RAM), such as synchronous dynamic random access memory (SDRAM), first-in-first-out (FIFO) memory, or other known storage media.
[0201] Microprocessors are based on integrated circuits, which makes it possible to perform arithmetic and logical operations based on (two) binary values (the simplest 1 / 0). For this to happen, the binary values must be available to the processor's computational units. The processor unit needs to obtain two binary values to compute the result of the expression a = b with operand c. The time spent retrieving data for these operations is called latency. These latency levels are wide-ranging, including registers, L1 cache, memory access, I / O operations or network transfers, and processor configuration (e.g., CPU vs. GPU). Because each individual component has latency, the total latency of computation is primarily a combination of the hardware components required in modern computing infrastructure to move data from one location to another. The difference between the fastest and slowest location where the CPU (or GPU) obtains data can be large (on the order of magnitude > 10^9).
[0202] In general, latency is the time delay between the cause and the result of some physical change observed or measured in a system. The latency used in this paper is directly related to the physical architecture of the multiprocessor system 2. The multiprocessor system 2 includes integrated circuit-based processor units 21, enabling arithmetic and logical operations based on (two) binary values (the simplest 1 / 0). These binary values must be available to the processor's computational units. The processor unit needs to obtain the two binary values to compute the result of the expression a = b operand c. The time spent retrieving data for these operations is called latency. These latency levels are broad, including registers, L1 cache, memory access, I / O operations or network transfers, and processor configurations (e.g., CPU vs. GPU). Since each individual component has latency, the total latency of computation is primarily a combination of the hardware components required to move data from one location to another within the infrastructure of the multiprocessor system. It is noteworthy that while microprocessor speeds have increased more than tenfold every decade, the speed of commercial memory (DRAM) has only doubled, resulting in a 50% reduction in access time. Therefore, memory access latency, measured in processor clock cycles, has increased sixfold in ten years. The multiprocessor system 2 exacerbates this problem. In bus-based systems, establishing a high-bandwidth bus between the processor and memory often increases the latency of fetching data from memory. When memory is physically distributed, network and network interface latency are added to the latency of accessing local memory on the accessing node. Latency typically increases with the size of the multiprocessor 1 because more nodes mean more communication about computation, more network jumps for general communication, and potentially more contention. A primary goal of parallel computing hardware design is to reduce the overall latency of data access by maintaining high scalable bandwidth, while a primary goal of parallel processing coding design is to reduce the overall idle time of processor unit 21. Generally, idle time of processor unit 21 can have several causes, such as memory access latency, deadlock, or race conditions, for example, if the order or timing of code blocks or threads processed by processor unit 21 is interdependent, i.e., dependent on the relative timing between interfering threads. As used herein, deadlock is a state in which one member of multiple processor units 21 is waiting for the output of another member (e.g., the output of an instruction block processed by another processor unit 21) to take action. Deadlock is a common problem in multiprocessing systems, parallel computing, and distributed systems, where software and hardware locks are used to arbitrate shared resources and achieve process synchronization. Therefore, the deadlock discussed in this paper occurs when a process or thread enters a waiting state because the requested system or data resource is held by another waiting process or has not yet been acquired by that process, which may in turn be waiting for another resource or data held by another waiting process.If processor unit 21 is unable to perform further processing because the resources it requested are being used by another waiting process (data access or output of another process that has not yet been completed by processor unit 21), this is referred to as a deadlock, which results in idle time for the corresponding processor unit 21.
[0203] The compiler system 1 includes means for translating the source programming language 31 of the computer program 3 into machine code 32 in the target programming language, which generates processing code 3.1, ..., 3.n. This processing code 3.1, ..., 3.n includes multiple instructions executable by or used to control the operation of the multiple processing units 21 of the parallel processing system 2. The source programming language may, for example, be a high-level programming language 31. The high-level programming language 31 may include, for example, C and / or C++ 311 and / or Python 312 and / or Java 313, Fortran 314, OpenCL (Open Computing Language) 315, or any other high-level programming language 31. It is important to note that the automatic parallel compiler system 1 can also be applied to the machine code 31 or assembly code 31 as source code to achieve code parallelization. In this case, the translation of high-level language to machine code instructions does not necessarily have to be performed by the compiler system 10.
[0204] The parallel processing system 2 includes a memory unit 22, which includes at least a main execution memory unit 221 / 2212. The main execution memory unit 221 / 2212 includes multiple memory banks for holding data for at least a portion of the processing code 32, and a transition buffer unit 221 / 2211. The transition buffer unit 221 / 2211 includes a high-speed memory for storing the starting location of the processing code 32 and a data segment that includes at least branch or jump instructions and / or memory references and data values used. The main execution memory unit 2212 provides a slower access time than the transition buffer unit 2211. The transition buffer unit 2211 may, for example, include a cache memory module 2211 and / or an L1 cache 22121.
[0205] The execution of processing code 32 by parallel processing system 2 includes the occurrence of latency 26, which is given by the idle time of processing unit 21 for retrieving and / or saving data required by processing unit 21 to execute a specific instruction block of processing code 32. Latency may include, for example, register 2211 access time and / or L1 cache 22121 access time and / or memory 2213 access time and / or I / O operation time and / or data network transfer time and / or processor configuration time.
[0206] The compiler system 1 includes a parser module 11, which translates the source programming language 31 into code 32 of basic instructions that can be directly executed by processing units 21. The basic instructions can be selected from a processing unit-specific set of basic instructions, which includes arithmetic operations 321 and / or logical operations 322 and / or control operations and / or I / O operations, particularly variable and array declaration instructions 323, comparison operation instructions 324, and code flow instructions 325 specific to the number of processing units 21. Arithmetic operations 321 may include, for example, addition, subtraction, multiplication, and division operations. Logical operations 322 may include, for example, multiple logical expressions, such as equality, inequality, greater than, less than, greater than or equal to, less than or equal to. Control operations may include, for example, "branching expressions" and / or "looping expressions".
[0207] As a variation of the embodiment, at least two processing units may, for example, have different basic instruction sets. Different processing units with different basic instruction sets may, for example, include a central processing unit (CPU) 210, a graphics processing unit (GPU) 211, a sound chip 212, a vision processing unit (VPU) 213, a tensor processing unit (TPU) 214, a neural processing unit (NPU) 215, a physical processing unit (PPU) 216, a digital signal processor (DSP) 217, a coprocessor unit (SPU) 218, a field-programmable gate array (FPGA) 219, etc.
[0208] The parser module 11 includes means for dividing the code of basic instructions into computational block nodes 333, each node consisting of the minimum possible segments of units that cannot be further decomposed, each unit comprising a sequence of basic instructions that requires the same input data. Two or more computational block nodes 333 (each node having a chain of basic instructions) form a computational chain 34, thereby creating an ordered flow of operations / instructions for the input data. The chains (sequences of basic instructions) in the computational block nodes 333 are constructed according to fixed rules: instructions are placed in chain 34 at positions where new basic instructions are read after basic instructions that write to data points. This automatically forms chain 34, which is data-centric and maps necessary, physically limited read and write operations to the computational registers 2211, L1 cache 2212, network I / O, etc. of the CPU 21.
[0209] The compiler system 1 includes a matrix builder 15, which generates multiple numerical matrices 151, ..., 15i from computation chains 34 based on a latency time 26. In the graph of computation chains 34, system dependencies can be evaluated, but these dependencies cannot be simply decomposed into individual chains. There are instances of merging and decomposition of computation block chains 333 within chain 34 due to data dependencies and / or code branching. The latency of information distribution in the hardware system is introduced as physical time. By allocating at least this time interval length to each computation block node 333, each computation block node 333 in the graph or tree structure can be numbered and assigned a block number based on its position in the graph, thus assigning the same number to computation block nodes 333 with the same "time position" in the graph. If the length of the computation block node 333 is at least the same as the time spent distributing information in the system and as many instructions as possible must be computed during this period, and each computation block node 333 is numbered according to the program flow based on its position in the graph, then a group of matrices 151, ..., 15i can be constructed.
[0210] Matrices 151,…,15i also indicate that they can be captured mathematically (graphical models based on CB, CC, etc., cannot be simply captured as tables / matrices). Therefore, data manipulation and communication are given and numerical matrices are constructed, which can be optimized (modified) for example using ML or AI, depending on the target platform and / or hardware setup.
[0211] The compiler system includes a numerical matrix optimization module 16, which uses numerical matrix optimization techniques to minimize the overall latency to a total latency 26 by providing an optimized structure of computation chains 34 processed by multiple processing units 21. Optimized machine code is generated for multiple processing units of the parallel processing system with the optimized overall latency 26 using a code generator 17. The optimization can now be applied to the hardware infrastructure. For each time unit and each independent chain and branch, the quantities important to the optimization are known numerically in matrices 151, ..., 15i: for example, based on the contents of the matrices: (i) the number of basic instructions that must be sequential, (ii) the size of the data transfer from computation block x in computation chain u, and when that transfer is needed again on computation block y in computation chain v (where y > x) (e.g., data can be located on the same cache line via a network or by combining computation blocks). For example, with a GPU, data should be copied from memory to GPU memory in a single processing step, and then all basic instructions with the same properties should be executed immediately. However, on a CPU, operations with the same data should reside on the same cache line (depending on the CPU), or operations of specific data types can be computed on the corresponding CPU using a better instruction set if necessary. In the system of this invention, even without optimization, this always results in parallel code because the basic elements are grouped sequentially in the CB.
[0212] In summary, since the (micro)processor only understands basic instructions, source code 31 is broken down into these basic instructions to achieve the most basic level of parallelization. (Note that the present invention is also applicable to technical problems of (micro)processor optimization based on the principle of integrated circuits (ICs), which are groups of electronic circuits. The instructions mentioned are associated with the configuration of electronic circuits on the (micro)processor, so the following subject matter also applies to any form of integrated circuit, and vice versa, and can be used to derive optimized integrated circuits (or configurations of electronic circuits or direct electronic circuits) for a given code, since instructions can be seen as a form of electronic circuit configuration representing computational operations (e.g., +, -, operation data, etc.). The following core points are key to the system of the present invention: (1) The basic instructions of the processor system are combined according to their unique “read” and “write” behaviors, that is, an instruction chain is formed in the node chain and linked to the computation block 333 according to the following rules: One instruction writes to X1, following the previous instruction that wrote to X1. The write instruction is followed by a new read instruction for X1. new instruction which reads to X1 is appended after the last instruction which writes to X1) "; (2) If information / data needs to be propagated in the multiprocessor system 2, a new computation block 333 is started; (3) Each computation block 333 has a minimum time length. This is similar to the process of transmitting / reproducing data to / from blocks in the hardware system. 333The time required to propagate information (data or signal) (delay) is proportional; (4) if the graphical model has two read data nodes, an instruction node and a write data node connected by links, the chains from computation block 333 have the following positions: the two chains (a) meet (e.g., because the instruction is read from two data points in two different computation blocks 333, or because there is a branch), (b) occur, e.g., if the two computation blocks 333 can be started by simultaneous reading. If necessary, the graphical model can also be based on more than two read nodes and several write nodes, or several instructions can be combined into one operation / instruction node; and (5) these chains 34 can be decomposed and the instructions and necessary information transmissions for each discrete time interval can be captured in a matrix. For example, each row is divided into several columns (one column for time intervals) and contains independent instruction chains and necessary information transmissions to other chains. Therefore, these are feasible for automatic optimization processes, especially numerical optimization processes. This provides a basis for fully automatic parallelization of source code. It is important to note that in this automatic parallelization system 1, the graphical model is not only based on matrix or tabular representations, but also provides a multidimensional nested tree structure of computational block graphs as task graphs associated with the computational parallel chain 34. This allows system 1 to evaluate properties that can be used for automatic parallelization, code optimization, computational block scheduling, and even automatic cost estimation or automatic mapping to different architectures of the multiprocessing system 2.
[0213] As described above, in the computation matrix, the cell contains the instruction chain 34 given by the sequence of computation block nodes 333 forming the chain 34, while in the transfer matrix, the cell contains transfer attributes, i.e., transfers to and from other computation block nodes 333. Note that the transfer attributes include what information is needed in another computation block node 333. Depending on the level of the target infrastructure, this can be addressed by classical compilation / processor control = transfers in the cache (the classical compiler distributes data to registers and attempts to utilize data locality to efficiently use the cache level) or explicitly shared by shared memory and protected by locks or explicitly using, for example, a message passing interface (MPI) protocol to send and receive data from / to different nodes in the cluster or via sockets in multi-core inter-process communication (IPC), etc. The transfer attributes can have any form of communication, ranging from being handled by the processor (cache) or explicitly defined by the communication mode (e.g., IPC via queues, MPI, etc.). This allows the method of the present invention to be extended to various platforms and / or infrastructures. Thus, the transfer attributes can, for example, include information to send data %1 (an integer) to cell (1,7). Transmission and / or communication require a certain amount of time, which is typically directly dependent on the (transmission / communication) latency in a particular system. Finally, it must be noted that, as mentioned above, in a specific row of the computation matrix, column cells include instruction streams or sequences of instructions, where each column cell of that row includes one computation block node 333 in the sequence of computation block nodes 333, forming a chain 34 for that specific row. However, in certain embodiment variations, each cell in a row does not necessarily need to include an instruction sequence or instruction. One or more cells in one or more specific rows of the computation matrix can also be empty. This is also true for the transmission matrix. The sizes of the computation matrix and the transmission matrix (i.e., the number of rows and columns) are typically equal. The computation matrix and the transmission matrix provide a possible technical structure for automatic parallelization.
[0214] Technically, the matrix builder follows the program flow from parser module 11 (e.g., Figure 35 ) and / or code 32 connect computation block nodes 333 respectively. Program flow is represented by connecting computation block nodes 333 (similar to basic blocks). For example, when a new instruction (=operation node) is added, a new computation block node 333 can be generated, where, generally, there are no explicit dependencies (see See Figure 21 The new computation block node 333 is located after another computation block node 333 or under a branch node. After adding all instructions, each computation block node 333 can be numbered along the program flow, forming a sequence of chains 34 thus generated. These numbers (block numbers) are equal to the columns of the matrix. Computation block nodes 333 with the same block number are distributed to different rows of the same column of the computation matrix. Task and gamma structure / graphic generation
[0215] So far, we have explained how to group basic instructions from sequential source code (serial instruction list) into computational blocks (CB = preferred list of instructions to run serially) as defined here, and index the resulting groups to retrieve instruction sets to be run in parallel, including the transfers required to run on different computational units. This method is built upon the systems perspective of modern computing platforms, which are still limited by binary computation steps. This fundamental concept (i.e., how to compute mathematical operations (e.g., +, -, ...) on a binary computing system (i.e., digital processor 2102 / 2103))... (i) In order to compute the statement a=b <op>c. The bit patterns b and c, each representing a number of the corresponding precision (int to double precision), must be physically available to the binary computation unit during computation; (ii) In order to transmit bit patterns a, b, or c on the platform or system, a delay time Δ will occur. transfer (iii) The Δ transfer This is at least a power of one higher than the number of instructions computed serially on a single computing unit (i.e., a processor 2102 or processor core 2103). Grouping is based on data dependency extraction, thus grouping instructions into computational blocks (CBs). Each computational block consists of a sequential chain of instructions. All necessary data transfers between CBs are preserved. This combination enables the optimization and automatic parallelization of source code to be processed separately on parallel computing units (i.e., processor 2102 and processor core 2103) in a hardware-independent manner, without any programmer prompts.
[0216] The variant implementation uses systems and methods located in the middle of the automatic parallelization compiler; see [link to implementation details]. Figure 84 The generated results can be presented as tensors or graphs, depending on the representation; see [link to relevant documentation]. Figure 85 If the code is represented by a tensor (or matrix), it consists of computational blocks and the chain of instructions within each unit. Each row represents a group of instructions that can be computed independently of grouped instructions in other rows of the same column. In the second matrix, corresponding data transfers are collected between the instruction groups. Figure 80 It also shows how tensor entries can be represented graphically. It's important to note that since CB A is positioned in the row and column of the earliest possible segment number (segment number A=B+1 (1CB corresponds to the potential transmission time) after data is available in CB B, consecutive entries in the computation matrix belonging to the same condition are based on the same data read. These consecutive segments can be called computation segments and indicate that consecutive CBs can be computed without additional information. If there is one edge between two gamma nodes, the gamma nodes can be combined into one gamma node (…). + => This allows them to be grouped into the same gamma node because they are based on the same data in the same way as consecutive CBs on the same row belonging to the same branch node. By definition, such computational segments are computational block nodes 333 because they contain arbitrary series of sequential instructions that do not share any data dependencies. Applied to the Fibonacci case, this is in Figure 85 As can be seen in the text, and produces works such as V. Sarkar's " Fundamentals of the parallel programming module parallelism (Fundamentals of Parallelism) The calculation graph in the example of "Expanded Case" is for illustrative purposes, to illustrate... Figure 75 How the method applied to LLVM-IR generates gamma maps. Figure 30 The diagram illustrates how this method forms at least one consecutive CB series at different branch nodes, thus maintaining program flow from the calling program (represented by main()) to the program's termination (represented by return(0)). This is in Figure 85 This can also be seen in the diagram. When interpreting this gamma graph on a multi-threaded platform, each edge represents a latency introduced for context switching. (a) Merge lines / CBs into a task
[0217] Similar to the indexed version, CBs that can be computed in parallel are located in the same column, meaning they have the same segment number. CBs with the same segment number can be grouped together (see [link]). Figure 39 In this step, the instructions in the new computation segment are added together, and any potential transfers between units disappear; see [link to relevant documentation]. Figure 11 This will affect the time required to compute CB in parallel or serial mode.
[0218] Another representation is a computational or task graph, which we will refer to as a "gamma graph" in this paper. To distinguish it: (i) Calculation graph For reference (see V. Sarkar’s Fundamentals of Parallel Programming Module 1 Parallelism; see above), where nodes consist of instructions in any order within the ideal parallelism domain; (ii) Task Map It is a general graph with tasks, regardless of how these tasks are formed (e.g., as a computation graph or in the sense of a function in the field of functional programming). (iiii) Gamma diagram A gamma graph is a graph where each node is a CB (Compute Block) or a combination of CBs. A gamma graph is a task graph and, initially at the granular level, a computation graph. Gamma nodes represent computational segments, as described above.
[0219] Each node represents one or more computation blocks (CBs). If, within a row of the tensor representation (i.e., on a single cell), there are no entries for inter-column transfers, computation blocks can be combined into a single computation segment. For each row, different computation and communication sequences are developed. A gamma node consists of at least one computation block node (CB) or several combinations having the same segment number and / or the same computation segments. Thus, a physically-based, unique dynamic task granularity of code can be obtained through the system and method of this invention, as described below.
[0220] Furthermore, the decomposition using this method results in different segments for computation and communication within each row (see tensor representation) or node (see gamma graph). Corresponding parallel code can be generated based on the gamma nodes; see [link to gamma graph]. Figure 87 Δ It is the calculation time, Δ It refers to communication / transmission time. Figure 87 The different computation and transmission / communication components are shown. Computation time Δ and communication / transmission time Δ Both are readily available and do not need to be platform-specific, but the unique feature of this approach is its ability to extract these two distinct attributes from the code during compilation. This allows for optimization of the allocation of nodes (code blocks) to available computational units using available frameworks (e.g., OpenMP, MPI, or others).
[0221] In summary, the automatic parallelization method and system of this invention group and index instructions in sequential code, providing the code in the form of grouped instructions for computation and the generation of communication (data transfer) portions, which can be represented as tensors or graphs. The computation portion can be viewed as a task with corresponding transfers / communications with other tasks. Task construction follows a fundamental physics principle: distributing data (bit information) across different computational units introduces transfer and can reduce computation time. It is a method of generating physics-based data blocks at a granularity different from that of the code. By combining only parallel CBs, this method can generate task graphs with different task granularities. The ability to generate such task graphs for a given code brings new opportunities for automatically optimizing / parallelizing code to a given hardware consisting of more than one computational unit. Combined with solutions to solutions to the NP-complete problem that may arise in job / task scheduling on parallel machines, the method of this invention is a general approach to distributing code to homogeneous or heterogeneous platforms.
[0222] The granularity of each task can be represented as G=Δ / Δ For example, see J. Kwiatkowski's " Evaluation of parallel programs by measurement of its Granularity (parallel program evaluated by measuring particle size) "Granularity is related to the level of parallelism. Several levels of parallelism exist (see above): (a) Instruction parallelism: Instruction-level parallelism (ILP) produces very fine-grained parallelism and is utilized by analyzing instruction dependencies. The hardware scheduler of a microprocessor (i.e., a microcontroller) also implicitly utilizes ILP; (b) Data parallelism: Many program operations are applied to elements of a large data structure. These operations can be performed on parallel or distributed systems; (c) Loop parallelism: Loop iterations can be executed in parallel if they have no dependencies. If all loop iterations require the same execution time, allocation can be easily done by static allocation, where the number of iterations per computational unit is fixed; and (d) Task (or thread) parallelism, which is defined more in the sense of functional parallelism. The heavily simplified SOTA compiler is based on ILP and extends it to loop parallelism to some extent. In the SOTA compiler, breaking down the code into basic blocks is the first step. A basic block (BB) is a sequence of instruction code without jumps or interrupts. This means that there are no branches other than one branch at the entry and one at the exit (see: Hennessy, John L.; David A. Patterson, Computer architecture: a quantitative approach method) (Elsevier, 2011). The method of the present invention extends the basic block concept and extracts possible parallel instructions for each BB and corresponding transfer options between BBs in the corresponding control flow graph (CFG).
[0223] The following demonstrates how the concept of basic blocks interacts with the method of this invention. Figure 88 The code in BB and CFG forms is illustrated schematically. Figure 89 The diagram illustrates a graphical representation of applying this method to a code-behind latent computation block (CB). The grouping and order of CBs depend on instruction-data dependencies within the CB. After indexing the CBs, the computation and communication segments evolve into two units, as shown below. Figure 90 As shown. T and F show the factors that determine the outcome. Figure 89 The conditional segmentation of the branch. If there are possible parallel instruction opportunities to parallelize the computation in BB, then the branch forms a transmission time Δ. This is in Figure 90 This can be seen in the first communication step.
[0224] For each path (based on a specific combination of conditions, representing a possible order of nodes throughout the code), extract the corresponding transmission size. S path1 、S path2 and S data See Figure 89 In the resulting parallel code, each branch transition (i.e., change of a basic block) has a corresponding transport, depending on the probability of instruction parallelism within each basic block. It is important to note that these transport properties can also disappear by combining CBs, leading to an optimization problem best addressed by a state-of-the-art compiler approach for a single computational unit. Computational segments can be viewed as tasks, while transports can be viewed as communication. Code, or program code, is a sequence of operations with a well-defined total order, where parallelism can be represented as a partial order. The computation graph used in this paper is a so-called direct acyclic graph (DAG), where each node is a sequential chain of instructions (=task), and edges are ordering constraints. The automatic parallelization method of this invention can automatically extract a computation graph (CG) G from the code (for information on computation graphs, see, for example, V. Sarkar's...). Fundamentals of parallel programming module Parallelism (the foundation of parallel programming modules) Several attributes are associated with the computation graph G, among which, runtime,p This refers to the parallel execution time, where P is the number of computational units. If we assume the execution time is time... (N) Given that the computation is uninterrupted and sequential, this does not depend on scheduling on a parallel machine: Total execution time of nodes in G: Work( ) = Longest path (critical path) in G -> Critical path length: ( ) Given the optimization (ideal) parallelism of computation graph G: Work( ) / ( )
[0225] For scheduling—the operation of allocating computational tasks to resources—understanding the length of each task and how they relate to each other is crucial for satisfying their constraints and scheduling them optimally. This is especially true for symmetric parallel architectures, where the computation time of the critical path (CB) is assumed to be small relative to the transmission time. Here, the critical path (longest path in G = CPL) is an important property, providing a measure of the degree of parallelization of a given code, since it is impossible to schedule the computation or processing of CG G in less than this time.
[0226] For executing G (schedule-independent) on a parallel processor machine with P processors: (1) the capacity limit is at least 1. runtime,p ≥ Work( This means that less than ) / P. runtime,p The runtime of is impossible to achieve on P processors (even with perfect partitioning); (2) the critical path bound is at least . runtime,p ≥ ( This means that, for a given code, it is impossible to have less than ) / P. runtime,p The time scheduling is parallelized because each scheduler must adhere to the dependencies in the critical path. Therefore, parallel execution time... runtime,p Given by the following equation:
[0227] In summary, the systems and methods of this invention provide a novel approach to extracting computational graphs for a given set of code. Using EV3, this can also be done for loop portions without explicitly resolving every data dependency between instructions. This enables new opportunities to automatically parallelize source code to hardware based on the latency characteristics of the hardware. This invention shows great potential, particularly by addressing the technical problem of loop-level parallelization, a core aspect of high-performance computing (HPC) applications, as loop portions can introduce significant computational demands. Applications where data is stored in random access data structures offer particularly opportunities to leverage the highly optimized parallelization of this invention. In this context, a well-known example of a technique for benchmarking automatic parallelization is a recursive or loop implementation for generating Fibonacci numbers, which will be discussed below. Furthermore, this automatic parallelization compiler is able to form a task graph based on a given transfer time (TT) when considering transfer time as the overhead of parallel machines running applications in parallel (e.g., context switching in a threaded environment). That is, the systems of this invention can provide specific automatic parallelization that generates optimized parallel code optimized for hardware-specific characteristics to run tasks in parallel on the parallel processing system used (particularly a specific architecture of one or more multi-core central processing units (CPUs)). (b) Length of transmission matrix elements and task computation
[0228] Generally, this method can be used to obtain the computation graph defined in an ideal parallel domain from the code, comparing it to V. Sarkar's... Fundamentals of the parallel programming module parallelism (Fundamentals of Parallelism) This allows us to infer certain code characteristics when applying the following assumptions: the execution time of all nodes is known, sequential computation is performed uninterruptedly, and this time is independent of scheduling, with no processor constraints. As mentioned above, for optimal scheduling—the operation of allocating computational tasks to resources—knowing the length of each task and how they relate to each other is crucial for satisfying their constraints and scheduling them optimally, i.e., achieving optimal optimization.
[0229] To measure the performance and hardware-specific parameters of the processor 2102, processor core 2103, or parallel processor architecture, measuring clock speed frequency is insufficient for the automatic parallelization system 1 of this invention; more accurate parameters are needed to measure performance. It is important to understand that today, there are numerous processor types and brands on the market, with significantly different hardware attributes and characteristics: Intel, AMD (Advanced Micro Devices, Inc.), and ARM (Acorn RISC Machines or Advanced RISC Machines) are examples. Each company offers multiple different architecture types and processor tiers, further complicating matters. To best optimize parallelization, accurate methods are needed to compare the computational capabilities of these processors. One possible way to measure processor performance is to measure instructions per second (IPS). Therefore, IPS (currently typically measured in MIP (millions of instructions per second) or GIP (billions of instructions per second)) can be used, for example, as a measure of the speed of the processor 2102 / 2103 and can be considered a general measure or benchmark of how many instructions the processor 2102 / 2103 can process in one second. However, for example, with Complex Instruction Set Computers (CISC), different instructions take different amounts of time, so the measured value depends on the instruction combination. Even when comparing processors from the same series, IPS measurements can be problematic. Many reported IPS values represent "peak" execution rates on artificial instruction sequences with few branches and no cache contention, while real-world workloads typically result in significantly lower IPS values. Memory hierarchy also greatly affects processor performance, an issue that traditional IPS measurements do not adequately account for. Therefore, there is no suitable method to measure MIPS, and MIPS measurements cannot be used as a measure of instruction execution speed required by System 1 of this invention, but at best as a measure of task performance speed compared to a reference value. In summary, the speed of a given processor depends on many factors, such as the type of instructions being executed, the execution order, the presence of branch instructions (which presents problems in the processor pipeline), and different cache levels.
[0230] Please note again that processor instruction rate is different from clock frequency, because each instruction may require several clock cycles to complete, or a processor may be able to execute multiple independent instructions simultaneously. MIPS can be useful when comparing the performance of processors built using similar architectures (e.g., Microchip-branded microcontrollers), but it is difficult to compare between different CPU and processor 2102 / 2103 architectures. In particular, MIPS measurements with higher numbers are not very meaningful for the practical operation of current systems 1, which require precise hardware-specific measurement parameter values. Regarding processor architecture, the design process involves selecting an instruction set and a specific execution paradigm (e.g., VLIW or RISC) and generating a specific microarchitecture, which is typically described in, for example, VHDL or Verilog. For microprocessor design, this description is fabricated using some of the various semiconductor device manufacturing processes, resulting in a bare die bonded to a chip carrier. This chip carrier is then soldered onto a printed circuit board (PCB) or inserted into a socket on the PCB. The operating mode of any processor is the execution of a list of instructions. Instructions typically include those for calculating or manipulating data values using registers, changing or retrieving values from read / write memory, performing tests on relationships between data values, and controlling program flow. The processor clock speed, mentioned earlier, is another metric typically measured in megahertz and gigahertz. However, as stated above, clock speed alone is not an accurate method for measuring the processor performance of this invention. Finally, FLOPs (floating-point operations per second) remain another factor in measuring processor performance. Floating-point numbers are numbers with a floating decimal point, such as 0.008. However, the FLOP benchmark only measures floating-point operations, not integers, meaning it cannot be used alone to measure processor performance.
[0231] Therefore, measuring the execution time of a single CB in isolation is neither efficient nor practical. However, the SOTA compiler approach is built to optimize a given set of instructions on a processor (NP-complete optimization). The proposed inventive system does not alter any indication of how instructions are scheduled on the processor. For the inventive system, the relative computation time of a CB is more relevant than the absolute computation time of a specific instruction or a single CB. The goal is more to determine the relative durations of different CBs and to separate computation time from data loading and storage (affected by memory hierarchy, e.g., cache access), which is represented by transfers in the approach (e.g., in multi-core architectures, data between computation units can be shared by L2 or L3 caches, and the optimization of the inventive system is to distribute CBs as transfers occurring on L2 / L3 caches). The SOTA compiler approach can be used to compile code within a CB into machine code. Modern SOTA compiler approaches aim to leverage processor features (e.g., instruction parallelism by using, for example, appropriate specific registers (e.g., XMM registers), floating-point units, out-of-order execution, etc.) for a given set of instructions (primarily within the scope of basic blocks). This leads to machine code optimization of the target computation unit. As mentioned earlier, there are established methods for determining the duration of a single machine instruction cycle, which is a function of the processor clock speed; see A. Fog, " Instruction tables "Technical University of Denmark, 2022." Based on the table values of these machine instructions and the available latency as a function of data size and data hierarchy (e.g., cache level, memory, etc.), the relative duration of computation CB can be derived. In this way, the best use of scheduling individual instructions is covered using well-established SOTA compiler methods that cover the NP-complete problem of instruction scheduling for a computation unit / processor. This process also derives a set of instructions in arbitrary order and the data size S required to compute that instruction set on a given hardware. comp The relationship between these components, combined with clock speed frequency, allows modeling the computation time differences between different chain blocks (CBs) (i.e., a series of sequential instructions). Since CBs in the same column represent unique and distinct sets of instruction chains and have no data dependencies, relative runtime can be approximated by the number of instructions, the specific number of cycles per instruction, and memory accesses. It is important to note that the instruction chain in consecutive CBs is always based on the same unique first "read" information (within a CB, the read value of the next instruction is directly following the write instruction = the definition of compute block node 333). Any other information required for computation in a CB is collected through transfers in the transfer matrix. This fundamental property of data locality allows it to be deduced whether this data can reside on different memory hierarchies (cache, memory, disk, or network, etc.). Combinations of CBs in the same column differ because this indicates that data dependencies can be utilized, for example, through cache levels. This effect can be detected by accumulating the data size of all parallel CBs, as this is the minimum data size that needs to be loaded into registers, and the latency of the corresponding cache level that can retain information can be derived. Because data is loaded in blocks (e.g., page size, cache line size, etc.), the minimum number of loads for a given data level can be determined and used to write parallel code with optimized data locality.
[0232] These methods do not imply providing a better way to optimize instructions on a processor, but rather leveraging different levels (ILP to LLP) and providing a structured way to construct physical-based instruction blocks based on their data locality. Based on these different instruction blocks (CBs), a general optimization problem can be derived to optimize (a) to physical relationships (b) – referenced as rel1: I. This method yields a computation graph, so for each level in the graph, the maximum number of unique chains of parallel instructions (CBs) in any order is known as a function of runtime parameters. II. The computing unit / processor has: i is a delay time set used to retrieve data of a given size (data size matched to registers, Ln-cache, memory, disk, etc.). ii. For a given set of instructions, what is the minimum required data size / input bit size? To compute a given set of instructions on a given processor or combinational circuit. iii. For a given set of instructions, different computation times are given on the processor / combinational circuitry by calculating the correspondence of the sequential instructions (instruction set, processor architecture, cache and memory layout, or combinational and sequential circuitry).
[0233] This means that for each gamma graph level, (a) the number of different CBs, (b) the minimum size of instructions in the CB for each CB, and (c) the required "read" and "write" data sizes (represented as data transfers) are known as functions of runtime parameters during compile time. IDL-points represent gamma nodes, where, when and They do not have the same runtime, so they can be used for all The size of the transmission and computation problem At that time, the processor will use idl (for example, see Figure 80 , return(0)). This information is extracted in a generic form from any given code, because information about data relationships must be in any form of runnable code.
[0234] To summarize, along the gamma map with initial granularity = computational graph, see II above - referenced as rel2: (1) Each level specifies the number of parallel gamma nodes. Each CB consists of a unique instruction chain. Figure 80 : , , ) (2) For a given platform, each node has a different data size required for computation instructions. (Functions with variable types, processor attributes, and available SOTA compilation methods) (3) The unique inputs and outputs of known gamma nodes
[0235] The same information is contained within the tensor notation. Extracted using this method... and Given: a) Problem size at each graph level (the sum of the sizes of all parallel computations in Parallel CB) (a) a unique set of instructions that can run in parallel, (b) the computation of each gamma node. The required size. Therefore, Define the minimum register size (or using a higher memory hierarchy) for computing the instruction set in a CB on a given platform, and define the different minimum areas required on the silicon wafer if the CB is considered a combinational circuit, N. Weste, et al. CMOS VLSI Design, A circuits and systems perspective (CMOS VLSI involves circuit and system perspectives) ", Addison-Wesley, 2011. Combined The number of loads of the fastest available memory hierarchy (memory, triggers, etc.) is known. These size properties are known in EV3 as functions defined for loop variables and loop heads. Based on this EV1, the method is able to correlate (1), (2), (3) (see rel2) with (i), (ii), (iii) (see rel1), thus enabling numerical optimization.
[0236] This laid the foundation for various optimization methods in practical applications, since no ideal parallelism assumptions were given in practical applications. Optimized scheduling of the loop section – loop-level parallelization
[0237] Loop-level parallelism is a core aspect of high-performance computing (HPC) and high-performance technical computing (HPTC) applications because loop-level code can introduce significant computational demands. HPC and HPTC utilize supercomputers and computer clusters to solve advanced computational problems. In particular, with the ever-increasing complexity of integrated circuit (IC) design at nano- and mega-scale, multi-core CPUs and GPUs have become ideal hardware platforms for emerging parallel algorithms. Today, multi-core processors are widely used in many application areas, including general-purpose, embedded, networking, digital signal processing (DSP), and graphics (GPU). The number of cores can reach dozens, exceeding 10,000 for dedicated chips, and exceeding 10 million in supercomputers (i.e., chip clusters). Parallelism (especially optimized loop parallelism) is technically absolutely necessary to effectively utilize such platforms. However, one technical challenge of parallelization also stems from the fact that leveraging ultra-large-scale parallel hardware platforms above 22nm and 60GHz becomes extremely challenging when complex source code and algorithms (e.g., circuit simulation) exhibit strong data dependencies. The automatic parallelization system of this invention provides data dependency elimination in the parallelization of complex code (e.g., technical circuit simulation, such as parasitic extraction, transient simulation, and periodic steady-state (PSS) simulation), paving the way for unleashing the potential of parallel hardware platforms. Performance improvements gained through the use of parallel processing systems (e.g., multi-core processors) depend heavily on the level of parallelization achieved. Specifically, the potential gains are limited by the portion of parallelized code that can run concurrently on multiple cores or processors; this effect is described by Amdahl's law. In the best-case scenario, so-called highly parallel problems can achieve speedup factors approaching the number of cores, and even higher if the problem is decomposed sufficiently to fit the cache(s) of each processor or core(s) to avoid using the much slower main system memory. In the prior art, most applications do not achieve significant speedup even with refactoring. The automatic parallelization system of this invention allows for the highest possible optimization, where data dependencies in the columns of the computation matrix disappear.
[0238] Loop-level parallelism in computer architecture is highly complex. The technical goal of loop-level parallelism is to extract parallel tasks within loops to accelerate the process. This parallelism is particularly needed when data is stored in random-access data structures such as arrays. A sequentially running program would traverse the array and perform operations on the indices one at a time; parallelized code with loop-level parallelism would utilize multitasking / multithreading / multiprocessing, where operations on indices are performed simultaneously or at different times. As mentioned earlier, opportunities to leverage parallelism primarily exist in applications where data is stored in random-access data structures. Within loops, data dependencies can be categorized as follows: Table: This table illustrates the "read" and "write" dependencies captured by the system and method of this invention.
[0239] The key difference lies in "loop-carried" dependencies and "loop-independent" dependencies. In the case of "loop-independent" dependencies, there are no dependencies between statements in each iteration, for example:
[0240] In contrast, there are circular dependencies, such as:
[0241] For this application, the following classification can be used: (1) Distributed loop: Unrelated statements can be extracted and calculated in separate loops and distributed in this way;
[0242] (2) DO-ALL parallelism (Independent Multithreading (IMT)): It can extract statements within a loop that can be executed independently. Therefore, all statements in the loop kernel can be executed independently;
[0243] (3) DO-ACROSS Parallelism (CMT): It can extract statements that can be executed independently and run simultaneously and computed separately;
[0244] (4) DO-PIPE parallelism (pipeline multithreading (PMT)): Parallelism is utilized when loop iterations are distributed on synchronous loops.
[0245] Distributed loop parallelization is the simplest form of parallelization and therefore requires no further explanation. In DO-ALL parallelization, each iteration of the loop executes in parallel and completely independently, with no inter-thread / inter-task communication, just as in distributed loop parallelization. Iterations can be assigned to threads / tasks in a round-robin fashion. The round-robin method is a scheduling method for handling queues, etc. For example, the round-robin method can be used as a process scheduler, where it allocates limited execution resources to several competing processes, or in parallelization, it treats processing units as processors. The loop program assigns all processes consecutively to one or more execution units within a short time slot. In the technical field, this process is also called arbitration. In parallelization, loops can be used, for example, for load balancing of processing units. DO-ALL parallelization and distributed loop parallelization are only possible if the loop does not contain dependencies carried by the loop or can be modified to prevent conflicts between concurrently executing iterations. Loops that can be parallelized via DO-ALL parallelization may experience speedup because there is no overhead of inter-thread communication. However, the lack of communication also limits the applicability of this technique, as many loops are not suitable for this form of parallelization.
[0246] In DO-ACROSS parallelization, similar to independent multithreading, iterations are distributed to threads / tasks in a cyclic manner. The optimization techniques described for increasing parallelism in independent multithreaded loops can also be used for cyclic multithreading. In this technique, dependencies are identified by the compiler, and the start of each loop iteration is delayed until all dependencies of the previous iteration are satisfied. In this way, the parallel portion of one iteration overlaps with the sequential portion of subsequent iterations. Therefore, it ultimately achieves parallel execution. Once all cores have started their first iteration, this can achieve near-linear speedup if the parallel portion of the loop is large enough to allow full utilization of the cores.
[0247] DO-PIPE parallelization is a method for loop parallelization with cross-iterative dependencies. Here, the loop body is divided into multiple pipeline stages, each assigned to a different core. Each iteration of the loop is then distributed across the cores, with each stage of the loop executed by the core assigned to that pipeline stage. Each individual core executes only the code associated with the stage assigned to it. However, there is no consistent way in the prior art to handle and automate loop-level parallelization, particularly at the level of automatic parallelization, as provided by the system of this invention.
[0248] In compiler technologies, such as for Low-Level Virtual Machines (LLVM), loops are represented as different nodes in a control flow graph (CFG). Note that the CFG used in this paper is not merely a graphical representation, but an accurate representation of the flow within a program unit, which is why it is used in compiler technologies and systems. The loop definition and its effect on sensed variables at runtime typically depend on runtime parameters. Because the locations of known changes in the code are known, the systems and methods of this invention... Read "and" Write enter The concept can be applied to array expressions within loop bodies. Therefore, the impact on array expressions with loop variable dependencies can be determined at compile time, as described above for determining the basic blocks in the loop body by differentiating different computation blocks (CBs): (1) reading data from a random access data structure (e.g., an array); (2) evaluating the statement; (3) writing the data back to the data structure. This is in... Figure 91 The diagram illustrates a simple loop portion in the control flow containing a loop body with LLVM IR code, and how this is generated by the method of the present invention. Read "、" calculate "and" Write "Compute block (CB). Utilize the form a[i+Δ ]=a[i+Δ ]+C (where, Δ =4 and Δ Taking a simple example of i=0, the CB in the loop (e.g., from i=0-7) can be as follows: Figure 92 As shown in the diagram.
[0249] As mentioned above, the cyclic part can be represented by a gamma graph with parallel task nodes, each of which has one or more combined computational blocks ( || ) and related iteration count ( loop ). Figure 93 This illustrates such a loop portion with parallel CB and explicit loop iteration.
[0250] In this form, the method transfers the body of the (nested) loop portion to either a distributed loop parallelism setting or a DO-ACROSS / DO-PIPE loop parallelism setting. As mentioned above, two different scenarios may arise when constructing gamma nodes based on the (nested) loop portion: Case 1 - A general-purpose CB with one read / write operation, which produces distributed cyclic parallelism. Case 2 - A general-purpose CB with K read / write operations, which produces DO-ACROSS / DO-PIPE loop parallelism. Resource-constrained hardware parallel processing architecture
[0251] For hardware parallel processing architectures with limited resources, the following situation may arise: due to limited resources, i.e., the number of available computing units... units < || In the method of this invention, gamma nodes are scheduled to different units The optimization steps differ in two cases: Case 1 - 1st read / write operation :like Figure 80 As shown, gamma nodes connected to one edge (or CBs with no entries in the transfer matrix in a row and the same branch nodes) can be combined, meaning that the CBs again construct clear "read" and "write" chains. According to... Figure 96 In the example, the loop is represented as a level. || There are gamma nodes, each with a length of . loop Given limited resources, optimization involves uniformly distributing these resources. || A gamma node. Since a gamma node consists of CBs with sequential instructions, it can be split between one of the sequential instructions, dividing the gamma node into two distinct units. See [link to documentation]. Figure 103 On each unit, evenCBs Scheduled, the remaining gamma nodes partialCBs ( evenCBs , partialCBs = divmod( || , units The additional transmissions are evenly distributed among the units. This is beneficial, as long as the increased latency from the additional transmissions is small enough compared to the corresponding distributed computing. Case 2-k read / write operations Optimization involves combining computational blocks (resulting in the disappearance of computational sums and transfers) to distribute the computational blocks evenly across the available resources. units One unit. In this case, the combination of CBs should minimize the resulting transmission.
[0252] It can be seen that, under the given assumptions, both optimization steps can be solved by the analysis engine (i.e., a system based at least on arithmetic logic units, control flow in the form of conditional branches and loops, and integrated memory). A method for solving a problem and being processed by a finite analysis engine in finite time is also called Turing-complete. In other words, the automatic parallelization system and method of the present invention provide a Turing-complete system because, for any class of automatic parallelization problems, every possible automatic parallelization of the source code can be computed on the computing system using the method of the present invention. Not all known prior art automatic parallelization systems are like this, which demonstrates the novelty of the system and method of the present invention in parallelizing the loop portion during runtime, as this presents the highest technical barrier in prior art automatic parallelization systems. In fact, it is noteworthy that the source code optimization parallelization specific to the hardware architecture of the present invention implemented by the system and method of the present invention is applicable not only to loop-level parallelization but also generally to source code parallelization. Assuming the computation block (CB) of… t computation Compared to t data-transfer The computational blocks within the columns of the computation matrix are relatively small, allowing for a uniform distribution of computational blocks to form uniformly long tasks distributed across parallel processing units / processors / cores. This still assumes... t computation < t data-transfer The number of CBs does not need to be evenly distributed across the parallel processing units / processors / cores available in a particular hardware, because if a variant of this embodiment is used, the number of CBs in a task can differ by at most 1. This holds true when all parallel processing units / processors / cores have similar performance characteristics and transmission latency is of the same order of magnitude.
[0253] As a variation of the embodiment, Symmetric hardware platform "Used as a foundation, the source code is automatically parallelized by a hardware-specific and hardware-optimized automatic parallelization system. The symmetric hardware platform has computational units (processors / cores) where all units have substantially the same computational power and the same transfer properties with each other. This typically applies at least roughly to the cores of a multi-core CPU. In this setup, the method of the present invention allows for Turing-complete optimization of gamma node scheduling, provided that the total computation time on a single unit is not faster than the overhead of running the problem on more than one unit. This is possible because all parallel CBs have the same computational requirements and thus the same computational workload, and all computational units can solve these computations simultaneously."
[0254] The automatic parallelization system and method of the present invention also allow for the introduction of new structures for handling (nested) loop portions in BB code, and for adapting to the number of processing units of a specific hardware architecture. units Constructing the task. Since analyzing all data dependencies within a loop is impractical (i.e., using a brute-force approach by trying all possible solutions is generally unsuitable for NP-complete problems such as loop parallelization), the method of this invention is used to... Figure 94 Breaking or constructing cyclic portions. Therefore, the system and method of the present invention allow the formation of gamma graphs solely based on cyclic portions in a CFG with BBs, without unpacking and analyzing all relevant data relationships (brute force). The system and method of the present invention construct a generic cyclic structure formed by CBs for cyclic portions.
[0255] When assigning gamma nodes of the loop portion to computational units, the following stages need to be distinguished: (i) initial stage Data is retrieved from the last write position (computation unit) before the start of the loop. (ii) Calculation phase : Compute parallel computations on a given computing unit || CB loop frequency (iii) Inner loop mapping phase Transfer data for the next iteration across all involved computing units. (iv) Results Phase When all computing units loop After each iteration, the data must be transmitted back to the host.
[0256] Depending on the target platform, different parts can be adjusted accordingly. For example, in a cluster configuration, where locally stored data is stored on disk and synchronized by the file system, there's no need to explicitly apply the results. Another example is in a multi-core environment where data is shared in memory. There, transfers are not explicit, but internal circular mappings can act as barriers to avoid race conditions (see above). Figure 95 The example shows four stages, in which, units = 4.
[0257] because || It is in the form of [ +Δ ]= [ +Δ The statement contains inherent read / write constraints, therefore the method of this invention can derive them by analyzing the array expression in the loop body. || And find the minimum read / write distance Δ rw This is certainly possible because array indices must be within the range defined by the array and must be positive natural numbers, otherwise the array cannot be accessed. When the loop variable changes (is written to) and must be able to be retrieved in any code, the change in indexes can be derived as a step during static compilation through analysis. This location in the code defines when this information is available during runtime, and therefore when dependent parallel opportunities can be taken advantage of. (Known) || Iterable loop variable restrictions loop This can be derived from the loop definition, and runtime parameters can be extracted during compile time. || and loop The system can analyze the reading and writing of array expressions during static compilation and generate numerical relationships between them. || (This can be a function with loop parameters) and loop The gamma graph of the function, thus producing a function with loop For the distributed loop of the next iteration, see [link / reference] Figure 93 This can be done without resolving every data dependency. || and loop In most cases, the scheduling of gamma nodes depends on the loop parameters and is therefore only known at runtime. If all parameters are known, the scheduling of gamma nodes can be optimized analytically during compile time. If the parameters depend on runtime, the system and method of this invention can be used to solve the scheduling analytically at runtime on a defined symmetric platform. There are two cases for optimizing gamma nodes as computational units. Scenario 1: General-purpose CB with one read / write operation
[0258] If there is only one read-write dependency in one or more array expressions, then the corresponding gamma node has Figure 96 In the form of, for example, [ + 3] = ( [ There is no inner loop mapping stage, and the present invention system 1 generates distributed parallelism. The computational load n of each gamma node loop, i It depends on the loop parameters, and therefore is runtime-dependent in most cases. But and Able to perform calculations through simple arithmetic processes: loop,dist , loop,reminder = ( tot , || In this context, each gamma node receives a CB (transmission) grouped together in a gamma node as a CB connected to one edge, and they construct an arbitrary sequence of sequential instructions. loop,i = loop,dist + loop,reminder,j , j [ loop,reminder Otherwise, j=0. Case 2: General-purpose CB with K read / write operations
[0259] If there are K reads in model CB that are dependent on the write, then the corresponding gamma node has a certain relationship based on... Figure 97 The general form shown in the examples, for example, a[i+5] = f(a[i], a[i-1]) There is an inner loop mapping phase, and the system of the present invention generates DO-ACROSS / DO-PIPE loop parallelism. Therefore, the system 1 and method of the present invention yield the following: Maximum parallel CB for each iterable loop step: || = (Δ rw ) = (Δ - Δ ) = Δ rw = 5 exist || = units : transfers When = 1, the transfer between each CB and the next iteration Initial granularity:
[0260] Using this, each gamma diagram and The function can be derived from the loop parameters by analyzing the code. Besides a write-to-read dependency, each read in the next iteration involves a transfer from other loop bounding boxes (CBs), which can be... || =Δ -Δ It disappears because it was computed on the same computational unit. In the case of several reads, || It is the minimum distance of all read-write differences, such as Figure 98 As shown. Distribute the workload of computation on a symmetric parallel processor
[0261] When all unified computing units have the same number of CBs, then execution with loops The iteration of an iterable loop requires the shortest runtime. This means that all parallel computation blocks ( || All can be distributed according to the relationship, where G is a set of weighted groups { w 1 ,…,w n A graph consisting of independent nodes of}, and k This represents the number of available processors. Therefore:
[0262] For real-time task scheduling on the aforementioned multiprocessor system, it's clear that no system can improve the given computation time, because scheduling must be at least as long as the maximum task and cannot be more efficient than keeping all processors continuously busy. The number of parallel task blocks (CBs) || Having the ability to utilize Δ in the inner loop mapping comp and having Δ comm The initial granularity of the required transmission . Will || Available quantity allocated to the same unit units It's a simple analysis of correlation. By combining CB, the system of this invention can generate corresponding... nunits The task graph can be divided into three cases: || > units : Optimize and combine parallel CB to obtain ('()" || = units There are definite available resources, and they can be used with... C's gamma node || < units There are more available resources than usable resources. use units = || and with 0 Running.
[0263] Then, the optimization step performed by System 1 of the present invention is to allocate parallel CBs according to the relationship (see above) to generate the optimal task granularity. nunits : (a) will || CBs are allocated to units To obtain a roughly uniformly distributed Δ on each computational unit. comp (b) By granularity nunit Minimize the transmission between gamma nodes to minimize Δ comp
[0264] Please note that step (a) is a step that the system 1 of the present invention can perform arithmetically, unlike step (b), in which the system 1 must optimize the inner loop mapping. It will be shown below that the system of the present invention can also perform this mapping analytically by simply combining CBs, thereby minimizing transmission, since transmission disappears when CBs are combined on a single computational unit. against nunits Inner loop mapping optimization
[0265] When parallel CBs are combined into gamma nodes (the resulting granularity is...) nunits When this happens, transmissions on the same unit disappear, but calculations are added together; see [link to documentation]. Figure 99 Through a very simple diagram, it can be proven that only combinations with one of these read / write distances can minimize the iterable cycle. loop The number of transmissions between gamma nodes in each iteration of ), which can be summarized as follows: Figure 100 As shown: The read access (the correct location in the IR statement or load) and the read count can be extracted; the read access count is expressed as... shifts . Number of transmissions per CB: transfers = shifts -1, because a single write-read can be optimized to disappear so that it can run on the same cell in the next iteration. The transmission size of each CB, where, T The size of a single transmission: transfer = transfers T for Figure 101 The example in the text produces transfer = 2 T CB not along the read shift combination: transfer,combo ( comb ) = comb transfers T Along the CB of the read shift combination: transfer,combo ( comb ) = transfers T = const
[0266] like Figure 101 As shown, according to transfers Any combination will produce a fixed result. transfer,combo Because when it exceeds comb When multiple CBs are combined into a gamma node, the reads occur within iterations from the same computational unit. This is achieved through statements. [ ][ ] = [ -2][ ] + [ +5][ To illustrate, some interesting properties can be observed (see...) Figure 102 ): T can be used to mark a size of 1. T The transmission depends on the array type 'a' By originating from the expression part ([ - 2][ ])of - =-2 and as part of the expression ( [ +5][ The result of ]) - =+5, the iteration distance for a loop iteration step of size 1 is comb,const = ( - ) - ( ( - )) = 7 When based on comb,const When the boundaries are combined into a single gamma node, two boundaries are formed: boundary A and boundary B. Combinations exceeding comb,const It will not increase or decrease the number of transmissions. Transmitting across boundary A: min(read-shift): 2 T Transmitting across boundary B: max(read-shift): 5 T Total transmission from gamma nodes at boundaries A and B to gamma nodes: T,const = (2 + 5) T = 7 T A gamma node with a CB has two transmissions: T,1CB = 2 T
[0267] In comb CB and comb > comb,const When combined, the number of transmissions becomes constant. T,const ,like Figure 103 As shown. This effect is also visible in the calculation. In Figure 101 Search range 1 < comb > comb,const When combining CB, the write-read distance must be combined according to the write-read distance, which will result in a linear increase in transmission. Scheduling in Case 1 - General CB with 1 read / write operation
[0268] If limited resources exist in a single read / write scenario, then the gamma node is allocated... units At that time, there may be some remaining: ( full partial = divmod( || , units ).in this case, partial Each gamma node must be evenly distributed among the available nodes. unit ,like Figure 103 As shown. This can be achieved by adding as ( full partial The additional transfer of the function is used to complete the process. Adding additional splits only makes sense if the portion of the CB allocated by adding additional transfers is no longer than if it were not split. Since gamma nodes (one or more CBs) contain instructions in arbitrary order, the position of the split is relative to Δ. comp No significant effect, can be achieved through partial / units To define. For example, based on units = 2 a[i+3]= [ In the case of ], this results in (1,1) = divmod(3,2), which in turn results in an additional transmission being added by splitting a gamma node. Scheduling in Case 2 - General CB with K reads and writes
[0269] If resources are limited, and ( full partial = divmod( || , units ) partial If the result is 0, then the computational workload can be balanced by minimizing the transfers. If partial results exist... partial If the value is >0, scheduling cannot be performed in a way that perfectly balances all units. This would result in other units being idle, but it is impossible to balance this inequality because all units have the same performance, transfers have all the same properties, and read shifts cannot reduce any transfers. Gaps in nested loops
[0270] A gap occurs in an iteration when the initial value and / or iteration step size in a (nested) loop is not equal to 1 and is read from / (or written to) the gap. This means that in a data structure, some values are never written into the loop, or some data is read from the CB before each iteration step (e.g., boundary conditions in a 2D heat equation). Figure 104 This is for indexing structured data and for gaps that occur when the entire array is not iterated over. Mapping and indexing of gamma nodes
[0271] There are different methods to implement the mapping. One method is to use the unrolled loop [0, || A global index is generated, which can be used to generate the start, end, and step size of all nested loops marked as gaps. Gamma nodes can then be mapped to the global index using the number of combined CBs for each gamma node, and local data indexes can be computed. The communication links for each stage include: (The text abruptly ends here, so the translation stops as well.) acronyms Boundary conditions (read from the gaps during the calculation phase) Inner loop mapping result
[0272] They can be easily found using computable array arithmetic steps. Other options are to use a bit array or compute global indices at boundaries A and B (see [link to relevant documentation]). Figure 102 (This depends specifically on the read shift of each gamma node, such as...) Figure 103 As shown. Another method is to calculate a simplified iterative step n for each computational unit based on runtime parameters. loop This is feasible at runtime, so the method can be used to optimize the loop portion on a symmetric parallel machine at runtime based on a model built at compile time. Further embodiments, variations and applications of the system of the present invention
[0273] like Figure 106 As shown, known technical problems in the field of parallel processing can be solved by means of the system and method of this invention. Specifically, Figure 106 Different embodiments of the system 1 of the present invention, EV1 to EV5, are shown. Figure 106 EV1 illustrates the most basic embodiment variant of the system 1 and method of the present invention and the basis for all other embodiment variants, wherein EV1 provides automatic parallelization of the code by optimizing the total latency to a minimum. If the number of available parallel processors (single-core 2103 and / or multi-core 2102) is limited, and (ii) the latency required for memory access and data transfer to and from processors 2102 / 2103 to the computation block node 333 computed on processors 2102 / 2103 is not small, then embodiment variant EV1 is based on some basic assumptions that the row dimension will be reduced to the number n of finite resources that can combine rows. units This optimization form is subject to the following assumptions: (i) any transmission introduces a significant delay compared to transmission vanishing in the transmission matrix. (ii) The differences between transmissions are very small. This means that all transmissions have approximately equal latency. Assuming (i) and (ii), the maximum row dimension in the computation and transmission matrices defines the system's combinatorial complexity (a certain number of CBs per BB). This can lead to potential limitations on combinatorial complexity, especially for cyclic parts and / or if (iii) the units have similar computational performance and the transmission latency between them is not given. Combined with EV3, general-purpose code can be optimized to (non)symmetric parallel machines. The following is a non-conclusive list of optimization options for tensor / gamma graphs. For each option, how to estimate computation and transmission times is noted: I. For the EV3 / loop portion on a symmetric platform: The optimization step is to parallelize n... || The gamma nodes are evenly distributed among the available cells. It is not necessary to know the exact number of gamma nodes. || Assigned to parallel unit n units The specific calculation / transmission time. For distributions on multi-core systems with cache latency awareness, it is necessary to know the specific calculation / transmission time for each n. units The data size is a function of the access latency to the shared memory hierarchy (cache levels and memory). This is possible because all n || Each parallel CB has the same properties in the computation and transfer matrix unit. This means that each CB has the same read, write, and computation properties. Therefore, (i) the different sequential instruction chains of each CB are known, and (ii) the corresponding data size required to compute the instruction set using a given processor is known. EV3 includes a process of constructing tasks from computation block nodes 333 belonging to the same column in the computation matrix, i.e., capable of parallel execution due to available data. The task construction allows for automatic parallelization of processor architecture-specific and / or system architecture-specific optimizations, where the number of processors 2102 / 2103, the performance of different processors / cores 2102 / 2103 and / or processor units 21, the size and response time differences of different memory units 22, and in particular, the differences in different processor registers 2211 and / or processor caches 2212 and / or RAM units 2213. II. According to Wall, David W.'s " Limits of instruction-level parallelism Limitations of parallelism "Proceedings of the Fourth International Conference on Architectural Support for Programming Languages and Operating Systems," 1991. The average dimension of the ILP in the basic blocks is approximately 3-4, and this is a bounded combinatorial problem when assuming the fundamental assumptions in EV1. By applying EV3 and assigning to all available units n... units This addresses the limitations of the cyclic portions. While all units are utilized in each cyclic portion, other acyclic portions can be optimized. This reduces the combinatorial complexity of scheduling the remaining basic blocks (i.e., computations without cyclic portions and the row dimension of the transfer matrix). To estimate the runtime of the CB, a model of relative computation time based on table cycle time and memory hierarchy access latency can be used, or different row combinations can be analyzed. III. By traversing the gamma graph: Starting from the parent gamma node, continuously combine child nodes until the target granularity is reached. Then, combine the nodes to form task 36, thus generating a task graph that forms tasks of equal length. This produces a task graph with a fixed granularity, thus allowing for targeting a given hardware granularity. Optimize the scheduling of objectives. Granularity can be estimated using # instructions, the cumulative cycle of instructions, and the corresponding data load of combined CBs. In this case, only the relative computational length between different CBs is important, which can be obtained from the table of instruction values; see A. Fog's " Instruction tables "Technical University of Denmark, 2022." This reduces the workload of scheduling tasks because they can be evenly distributed due to their optimized task granularity for a given platform. This is a bounded problem, but this method may miss some overall optimization opportunities. IV. In the context of EV2, a fixed-valued transmission time (TT) can be associated with a given input from the compiler for all transmissions (edges in the gamma graph). In this form, the gamma graph can be formed by combining parallel gamma nodes until their approximate computation time (e.g., derived from table values) is more advantageous in parallel computation than in serial computation. A preliminary study by the REDS Institute in Lausanne, Switzerland, demonstrates the feasibility of this approach in automatic parallelization. It can be shown that an adapted gamma graph can be constructed based on a given delay time TT to generate a delay-adapted task graph with corresponding task granularity. For this preliminary study, it is assumed that all parameters are known (without using E3). V. Using gamma graphs as input to form (mixed) integer linear programming problems: Construct a system of linearly optimizable equations, where the gamma graph EV2 represents a complexity similar to PCGmTSP. To estimate m distinct... Gamma node group, can be selected Tabular approach or profiled approach In conjunction with EV3, the loop portion can be associated with a different number (m) of usage units, depending on the parallel group at each gamma level.
[0274] at last, Figure 106 Variant EV4 (see also) Figure 110 This invention illustrates a system for optimizing integrated circuit (IC) or chip designs, which addresses electronic engineering problems in IC design by incorporating the logic and circuit design required for designing ICs. Specifically, the IC design provided by embodiment variant EV4 offers a digital IC design that can be used to generate components such as microprocessors (especially multi-core microprocessors), field-programmable gate arrays (FPGAs), memories (cache, RAM, ROM, and flash memory architectures), and digital application-specific integrated circuits (ASICs). ICs comprise miniature electronic components constructed as electrical networks on a monolithic semiconductor substrate via photolithography. The digital design implemented by embodiment variant EV4 provides a highly optimized IC architecture in terms of logic correctness, maximizing circuit density, and placing circuitry to route clock and timing signals most efficiently.
[0275] Below, some applications of System 1 and the method of the present invention will be discussed in more detail. (i) Automatic parallelization of the source code used to generate the Fibonacci sequence
[0276] Figure 75 An example is shown Figure 76 Visible in and as Figure 81 The construction of CB for the gamma diagram instructions (CMP, SUB, ADD). This is Figure 75 The recursive call to f(3) in the code is represented. Similar graphs can be retrieved when applying this method to a loop implementation of the Fibonacci sequence.
[0277] Different parallel processing implementations with varying performance properties are known for generating and computing the Fibonacci sequence. The following explains how this invention can be applied to implementations using a) recursive function calls and b) loops. Both implementations exhibit different performance characteristics. For an understanding of the processing problem, please refer to, for example, https: / / www.geeksforgeeks.org / program-for-nth-fibonacci-number / . Below is an example of the source code for processing the Fibonacci sequence recursively. / / Fibonacci Series using Recursion #include<studio.h> int fib(int n) { if (n <= 1) return n; return fib(n-1) + fib(n-2); } int main() { int n = 9; printf("%d", fib(n)); getchar(); return 0; }
[0278] Parsing the function code declared by fib(n) generates a pseudo token language, where the function code of fib(n) is as follows: int fib(n) { if (n <= 1) return n; return fib(n-1) + fib(n-2); } Table 1 below provides the pseudo-markup language: (Table 1)
[0279] Figure 41 and Figure 42 The diagram schematically illustrates the computation block node (CB), its operations, and the corresponding data nodes (similar to the labels in Table 1 above). Icons This indicates the location within the compute block node to which the transfer occurs (the start or end point of the compute block node). Recursive calls to the function produce additional transfers, such as... Figure 42 As shown.
[0280] The next step is to number the compute block nodes according to their call locations in the code. This will produce something like... Figure 43 The pseudo-image is schematically represented in the diagram, which then produces, for example... Figure 44 and 45 The calculation and transmission matrix is shown.
[0281] By combining the start and end communication units in the transmission matrix, eliminating empty units in the computation matrix, and bringing them back to different code segments, we obtain... Figure 46 The result is that, based on this code segment, code can be generated directly (as a compiler) or the code can be passed back and then used with the SOTA compiler to generate machine code (as a transpiler).
[0282] To demonstrate how the system and method of this invention offer advantages for compiling recursive implementations based on the Fibonacci sequence, the following paragraphs explain how the method of this invention maps and / or optimizes code with a more concurrent solution than the input code. As shown, it is the combination of lines that optimizes the code; the figure illustrates the combination of cbn in the branch node labeled branch2b (see...). Figure 43 And combine them, see Figure 48 Calling a function involves placing the computed block nodes in the correct positions within the matrix to apply the corresponding transfers, such as... Figure 47 As shown. Considering this, using the method of this invention, a recursive function call can be viewed as the transmission of function parameters and result variables in the return statement, as well as "reading" and "writing". Figure 48 .
[0283] Based on the example of fib(4), Figure 49 The paper demonstrates step-by step how the addition of computational block nodes and the reduction in transport (since everything is on a single computational chain) results in more optimized source code.
[0284] The depth of this chain depends directly on the number n in fib(n). Since recursive calls are easily detected in the code, it's easy to avoid implementing recursion across all dimensions in the final application. For ease of understanding, Figure 50 This is shown with some simplification. Step 4 shows the cbns call in the case of 'n=4'.
[0285] Figure 51 The next step in the diagram illustrates the transfer that will occur (transferring the information from the last "write" to the data node to the location of the data node where the "read" occurred, and remembering the information in the corresponding compute block node). Since all computations are on a single chain, the transfer will disappear, as... Figure 52 As shown. This will result in [the following] when solving each step. Figure 53 A program in Chinese format.
[0286] Substituting this into a matrix representation and bringing it back into the code, we can see the result is as follows. This produces more efficient code than the original fib (n=4) implemented in Table 1 above. Compiling this code using the SOTA compiler will produce even better optimized code than not applying this method. f(n) { if (n <= 1): return n; t1 = n-1 t2 = f(t1) t3 = n-2 t4 = f(t3) t5 = t2 + t4 return t5 } main() { r1w = f(1) r0w = f(0) r2w = r1w + r0w r3w = r2w + r1w r4w = r3w + r2w }
[0287] Recursive calls can also be interpreted as array operations similar to those described in this invention, because they transmit information (function parameter param[i]) to the corresponding cbns in the branch node of the function declaration, and then return (one or more) return values to a[i]. See [link to relevant documentation]. Figure 54 This produces a perspective also seen in partial differential equations. This implementation of the Fibonacci sequence will be further referenced below. However, as a next step, the following paragraphs will demonstrate the treatment of partial differential equations, which primarily results in nested loops and extensive use of array operations. (ii) Partial Differential Equations (PDEs)
[0288] According to the patent application, computational and communication models can be derived for a freely given PDE discretization by placing operation nodes based on "read" and "write" modes and resolving ambiguous dependencies through transmission rules. This paper will use a PDE with 2D heat equations, where the 2D heat equations are given by the following equations:
[0289] Discretization is performed using a finite difference scheme:
[0290] Figure 55 This shows a portion of the implementation in Python. Each entry in the array is a data node. Reading from an array index in a method results in an operation node with the index of the data node and the base address of the array. Array operations can be viewed as operation nodes with corresponding data nodes; see [link to relevant documentation]. Figure 56 .
[0291] For array operations a[i+ An example of a circular array where [iw] = a[i], Figure 57 The corresponding computation block nodes are shown. Taking this into consideration, the initial block ( Figure 55 ) can be in, for example Figure 58 The diagram shows a detailed representation of all calculations within the calculation block (see Figure 1). Figure 55 All of these occur within the j-loop. By using one-dimensional array notation and applying the basic rules of this method, a diagram illustrating the computation of block nodes within a loop is derived, as shown below. Figure 59 As shown.
[0292] An array read (e.g., u[k][i+1][j]) will create a computed block node, and metadata for transferring values to that index will be added to two CBNs: one for the "read" node and the other for the position where the data node was last written (e.g., at a[k+1][i][j]). This results in statements such as array operations in a j loop ( Figure...
Claims
1. Symmetric automatic compiler system (1) for automatic parallelization of hardware optimization of program code (3) to be executed by a multi-core or multi-processor parallel processing system (2) having a plurality of processing units (21) which simultaneously process instructions for data in the parallel processing system (2) by executing the program code (3), the automatic compiler system (1) comprising means for converting a serial source code (31) of the program code (3) written in a programming language into a parallel processing machine code (32) comprising a plurality of instructions executable by the plurality of processing units (21) of the parallel processing system (2) or controlling the operation of the plurality of processing units (21), wherein the parallel processing system (2) comprising a memory unit comprising at least a main execution memory unit (221 / 2212) comprising a plurality of memory banks for holding data of at least part of the processing code (32) and a transition buffer unit (221 / 2211) comprising a high-speed memory for storing a start location and a data segment of the processing code (32) comprising at least a branch or jump instruction and / or used memory references and data values, wherein the main execution memory unit (2212) provides a slower access time than the transition buffer unit (2211), wherein the execution of the processing code (32) by the parallel processing system (2) comprises the occurrence of a latency time (26) given by an idle time of a processing unit (21) between the processing unit (21) having processed a specific instruction block of the processing code (32) for data and the reception of data required for the processing unit (21) to execute a consecutive instruction block of the processing code (32), characterized in that the compiler system (1) comprises a parser module (11) for converting the serial source code (31) into a code (32) having a basic instruction stream executable by the processing units (21), the basic instructions being selectable from a limited set of processing unit specific basic instructions, and the basic instructions comprising only basic arithmetic and logic operations (321 / 322) and / or basic control and memory operations (325) for the number of processing units (21). characterized in that the parser module (11) comprises means for dividing the code (32) having the basic instructions into a plurality of compute block nodes (333), each compute block node (333) consisting of a minimum possible segment of a sequence of basic instructions of the code (32) processable by a single processing unit (21) that cannot be further decomposed, the minimum possible segment of the basic instructions being characterized by a sequence of basic instructions consisting of consecutive read and write instructions, the sequence being unable to be further decomposed by smaller sequences of basic instructions between consecutive read and write instructions, and the read and write instructions requiring to receive data needed by the processing unit (21) to process the sequence of basic instructions and to return the data after the sequence has been processed, characterized in that the compiler system (1) comprises a matrix builder (15) for generating matrices (151,...,153) from the compute chains (34) divided by the code (32), the matrices (151,...,153) comprising a compute matrix and a transfer matrix (151 / 152) and a task matrix (153), wherein each column in the compute matrix (151) comprises compute block nodes (333) that are simultaneously processable based on the executability of read and write instructions transferring data needed by the compute block nodes (333) to be processed, wherein the transfer matrix contains transfer and processing properties to each compute block node (333), the transfer and processing properties characterizing at least data transfer properties from one compute block node to a consecutive compute block node (333), the data transfer properties comprising at least a data size of the data being transferred and an identification of a source compute block node (333) and a target compute block node (333) of the data transfer and / or processing characteristics of one of the processing units (21), characterized in that the tasks (56) of the task matrix (153) are formed by the matrix builder (15), wherein in case the compute block nodes (333) each have different associated reads, the tasks (56) are formed by dividing the compute block nodes (333) of a column of the compute matrix (151) evenly into a number of symmetric processing units (21), forming one task (56) for each of the processing units (21) for each column of the compute matrix (151), and dividing the remaining compute block nodes (333) into at least a part of the tasks (56) based on a predefined scheme, and wherein in case the compute block nodes (333) at least partially have reads transferring the same data, the tasks (56) are formed by minimizing the number of reads evenly or substantially evenly over the number of processing units (21) and / or by minimizing the integrated processing time on each processing unit (21) evenly if a predefined offset value is exceeded, characterized in that the compiler system (1) comprises an optimizer module (16) which minimizes the aggregated latency time (26) integrated with all occurring latency times (261) using matrix optimization techniques by providing optimized structures of tasks (56) within the task matrix (153), wherein each column of the task matrix (153) forms a computation chain (34) by one or more tasks (333), creating an ordered stream of computation block nodes (333) to be executed by one of the plurality of processing units (21), characterized in that the compiler system (1) comprises a code generator (17) for generating the parallel processing machine code (32) for the plurality of processing units (21) with optimized aggregated latency time (26) based on the computation chains (34) given by the optimized task matrix (153).
2. The compiler system of claim 1, wherein, The parallel processing system (2) is a symmetric multi-core system and / or a multi-processor system with the plurality of processing units (21), wherein the symmetric multi-core system and / or multi-processor system is a system (1) with a plurality of cores (2103) or a plurality of processors (2102) which are all identical or substantially identical.
3. The compiler system of claim 2, wherein, The processors (2102) and / or cores (2103) have identical memory architectures and processor technology characteristics.
4. The compiler system of claim 3, wherein, The technology characteristics at least include identical processor (2102) or core (2103) performance with equal or substantially equal number of instructions processed per second.
5. The compiler system according to one of claims 1 to 4, wherein, The predefined scheme comprises splitting the remaining computation block nodes (333) by adding additional transfers for processing the respective computation block nodes (333).
6. The compiler system of claim 5, wherein, The defined scheme to split the remaining compute block nodes by adding additional transmissions includes: distributing the remaining compute block nodes (333) evenly to multiple processing units (21) by adding transmissions, as long as the added delay time of the added transmissions is less than the corresponding distributed compute time, and evenCBs , partialCBs ) = divmod( || , units ) is true.
7. The compiler system according to one of claims 1 to 4, wherein, The predefined scheme comprises splitting the remaining computation block nodes (333) by adding one computation block node (333) to each task (56) until no remaining computation block nodes (333) are left.
8. The compiler system of claim 1, wherein, The parallel processing system (2) is an asymmetric multi-core system and / or a multi-processor system with the plurality of processing units (21), wherein the asymmetric multi-core system and / or multi-processor system is a system (1) with a plurality of cores (2103) or a plurality of processors (2102), wherein at least some of the cores (2103) or processors (2102) of the plurality of cores (2103) or processors (2102) have different processor (2102) or core (2103) performance with different number of instructions processed per second.
9. The compiler system of claim 8, wherein, For a specific processor (2102) or core (2103) performance based on number of instructions processed per second, the computation block nodes (333) of a column of the computation matrix (151) are evenly split to the number of the plurality of processing units (21) by adjusting the length of the tasks (56) assigned to different processing units (21).
10. The compiler system of one of claims 1 to 9, wherein, The source programming language is a high-level programming language.
11. The compiler system of claim 10, wherein, The high-level programming language comprises C and / or C++ and / or python and / or java.
12. The compiler system of one of claims 1 to 11, wherein, The transition buffer unit comprises a cache memory module and / or a L1-cache.
13. The compiler system of one of claims 1 to 12, wherein, The delay time comprises a register access time and / or an L1-cache access time and / or a memory access time and / or an I / O operation time and / or a data network transmission time and / or a processor configuration time.
14. The compiler system of one of claims 1 to 13, wherein, At least two of the processor units have different basic instruction sets.
15. The compiler system of one of claims 1 to 14, wherein, The arithmetic operations comprise addition, subtraction, multiplication and division operations.
16. The compiler system of one of claims 1 to 15, wherein, The logical operations comprise a plurality of logical expressions, such as equal, not equal, greater than, less than, greater than or equal to, less than or equal to.
17. The compiler system of one of claims 1 to 16, wherein, The control operations comprise "branch expressions" and / or "loop expressions".
18. The compiler system of one of claims 1 to 17, wherein, The computation block node (333) is generated by mapping the read and write interactions of a single instruction, the mapping of the read and write of its data nodes (331) created by the operation nodes (332).
19. The compiler system of one of claims 1 to 18, wherein, The computation block node (333) is composed of connected operation nodes (332) which form a chain (34) having one or more input data nodes (331 / 3311) and one or more output data nodes (331 / 3312).
20. The compiler system of claim 19, wherein, The computation block node (333) is connected to a next computation block node (333), or to a control flow node (334), or to one or more input data nodes (331 / 3311) and one or more output data nodes (331 / 3312) of a building chain (34).
21. The compiler system of one of claims 1 to 20, wherein, Each pair of computation and transfer matrix is implemented by forming a single numerical matrix and / or a multi-dimensional numerical tensor, respectively.
22. The compiler system of claim 21, wherein, The optimization of the numerical matrix is implemented as a tensor optimization.
23. The compiler system of one of claims 21 or 22, wherein, The numerical matrix optimization or the tensor optimization by the optimizer module is based on a dedicated application machine learning structure.
24. The compiler system of one of claims 1 to 23, wherein, Each computation block node (333) of the computation chain (34) is numbered along an ordered flow of computation block nodes (333) within the computation chain (34) by assigning a block number to the computation block node (333), wherein in the computation and transfer matrix the block number of the computation block node (333) equals a column of the matrix, wherein computation block nodes (333) having the same block number are distributed to different rows of the same column.
25. The compiler system of one of claims 1 to 24, wherein, Each row in the computation matrix comprises a computation chain (34) of a processing unit (21), wherein a cell of the computation matrix comprises a computation block node (333) of the computation chain (34), wherein a cell in the transfer matrix comprises required transfer properties to and / or from other computation block nodes (333).
26. The compiler system of claim 25, wherein, The transfer properties of a cell in the transfer matrix comprise at least information required in another computation block node (333).
Citation Information
Patent Citations
Method and system for automated code conversion
US20080263530A1
Cited By
Staged multi-policy instruction scheduling method and system for VLIW architecture
CN122308925A
Staged multi-policy instruction scheduling method and system for VLIW architecture
CN122308925B
