Compiler, compiling method, and compiler device

The compiler addresses the challenge of parallelizing loops by checking for memory region overlaps and adjusting execution accordingly, thereby improving execution speed and consistency.

JP7653021B2Active Publication Date: 2025-03-28FUJITSU LTD
View PDF 4 Cites 0 Cited by

Patent Information

Application Number
JP2021089727
Authority / Receiving Office
JP · JP
Patent Type
Patents
Current Assignee / Owner
Filing Date
2021-05-28
Publication Date
2025-03-28
Estimated Expiration
2041-05-28

AI Technical Summary

Technical Problem

Existing methods for parallelizing loops in programs face challenges when memory regions referenced by different iterations overlap, leading to inconsistent execution results.

Method used

A compiler is developed to generate a second program that checks for memory region overlaps and executes processes either sequentially or in parallel based on overlap conditions, ensuring consistent results.

Benefits of technology

This approach enhances program execution speed by allowing parallel execution when memory regions do not overlap, while maintaining consistency by executing sequentially when overlaps occur.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure 0007653021000001
    Figure 0007653021000001
  • Figure 0007653021000002
    Figure 0007653021000002
  • Figure 0007653021000003
    Figure 0007653021000003
Patent Text Reader

Abstract

To increase an execution speed of a program.SOLUTION: A compiler causes a computer to execute processing of generating a second program that includes: a first code that determines whether a first area of a memory that a process inside a loop included in a first program refers to in a first execution time of the loop is in duplicate with a second area of the memory that the process refers to in a second execution time of the loop; a second code that executes the process in an order of the first and second execution times when it is determined that the first and the second areas are duplicate; and a third code that executes the process for the first execution time and the process for the second execution time in parallel when it is determined that the first and the second areas are not duplicate.SELECTED DRAWING: Figure 12
Need to check novelty before this filing date? Find Prior Art

Description

[Technical field]

[0001] The present invention relates to a compiler, a compiling method, and a compiler device. [Background technology]

[0002] Parallelization of a program is an effective way to increase the execution speed of a computer program. In particular, parallelization of loops that take up a large part of the program's execution time can efficiently increase the execution speed.

[0003] For example, if multiple iterations of a loop are each executed in parallel by multiple processor cores, the execution time can be shorter than if all the iterations were executed sequentially by one processor core.

[0004] However, when multiple iterations reference overlapping memory areas, the contents of an area referenced by one iteration will be changed during execution of another iteration, resulting in a different program execution result compared to when the program is not parallelized. [Prior art documents] [Patent documents]

[0005] [Patent Document 1] Japanese Patent Application Publication No. 11-272650 [Patent Document 2] JP 2013-242604 A Summary of the Invention [Problem to be solved by the invention]

[0006] According to one aspect, an object is to increase the execution speed of a program. [Means for solving the problem]

[0007] According to one aspect, a second program is generated, the second program including: first code for determining whether a first area of ​​memory that a process inside a loop included in a first program refers to in a first execution of the loop overlaps with a second area of ​​the memory that the process refers to in a second execution of the loop; second code for executing the process in the order of the first execution and the second execution when it is determined that the first area and the second area overlap; and third code for executing the process in the first execution and the second execution in parallel when it is determined that the first area and the second area do not overlap. the loop has a first array indexed by an execution time of the loop and a second array indexed by each element of the first array, the process is a process of storing a first element of the second array in the memory in the first execution time and storing a second element of the second array in the memory in the second execution time, the first area is an area in which the first element is stored in the first execution time, and the second area is an area in which the second element is stored in the second execution time. A compiler is provided for causing a computer to execute the process. Effect of the Invention

[0008] According to one aspect, the execution speed of a program can be increased. [Brief description of the drawings]

[0009] [Figure 1] FIG. 1(a) is pseudocode for a loop that can be parallelized, and FIG. 1(b) is a schematic diagram showing the storage locations of array elements array[i] and array[j] in memory. [Diagram 2] Figure 2(a) shows pseudocode for a loop that may not be parallelizable, and Figure 2(b) is a schematic diagram showing where the array elements “array[index[i]]” and “array[index[j]]” are stored in memory in this case. [Diagram 3] FIG. 3 is a hardware configuration diagram of the compiler device according to the first embodiment. [Figure 4] FIG. 4 is a schematic diagram showing the processing performed by the compiler device according to the first embodiment. [Diagram 5] FIG. 5 is a functional configuration diagram of the compiler device according to the first embodiment. [Figure 6] FIG. 6 is a flowchart of the compiling method according to the first embodiment. [Figure 7]FIG. 7 is a flowchart of the optimization process according to the first embodiment. [Figure 8] FIG. 8 is a schematic diagram of pseudocode obtained by converting intermediate code having non-memory dependency between iterations into source code. [Figure 9] Fig. 9(a) is a schematic diagram of pseudocode obtained by converting intermediate code having memory-mediated dependency between iterations into source code, and Fig. 9(b) is a schematic diagram showing each element “array[i]” and “array[i+1]” allocated in memory. [Figure 10] FIG. 10(a) is a schematic diagram of pseudocode obtained by converting the intermediate code that is the basis of the optimized code into source code, and FIG. 10(b) is a schematic diagram of pseudocode obtained by converting the optimized code generated from the loop in FIG. 10(a) into source code. [Figure 11] FIG. 11(a) is a schematic diagram of pseudocode obtained by converting intermediate code that has dependencies via other arrays into source code, FIG. 11(b) is a schematic diagram of memory to which arrays “array” and “index” are allocated, and FIG. 11(c) is a schematic diagram of memory when parallel execution is not possible. [Figure 12] FIG. 12 is a schematic diagram of pseudo code obtained by converting the optimization code 42 generated by the optimization code generating unit according to the first embodiment into source code. [Figure 13] FIG. 13 is a schematic diagram of pseudo code obtained by converting the optimization code 42 into source code when parallelizing processing by vectorization in the first embodiment. [Figure 14] FIG. 14 is a schematic diagram showing an example of the values ​​of the elements of the arrays "vectorizable" and "index" when the vector length "VL" is 2 in the first embodiment. [Figure 15] FIG. 15 is a flowchart showing the process when the target machine executes the first and fourth codes in FIG. [Figure 16] FIG. 16 is a schematic diagram of pseudo code obtained by converting the optimized code generated by the optimized code generating unit in the second embodiment into a source code. [Figure 17] FIG. 17 is a flowchart (part 1) of a process when the target machine executes the first code in the optimized code of FIG. [Figure 18] FIG. 18 is a flowchart (part 2) of a process when the target machine executes the first code in the optimized code of FIG. DETAILED DESCRIPTION OF THE PREFERRED EMBODIMENTS

[0010] Prior to describing the present embodiment, the matters considered by the inventors of the present application will be described.

[0011] As mentioned above, parallelizing loops is an effective way to improve the execution speed of a program.

[0012] Figure 1(a) shows pseudocode for a loop that can be parallelized. In the example in Figure 1(a), a loop using a for statement is assumed, and the process "array[i] = array[i] + 1" is executed in the i-th iteration. Note that the iteration is an integer that indicates the number of times the loop is executed.

[0013] FIG. 1B is a schematic diagram showing storage locations of array elements array[i] and array[j] in memory 1.

[0014] The above process "array[i] = array[i] + 1" loads the array element "array[i]" stored in memory 1, adds 1 to it, and stores the result in memory 1. The reference in memory 1 in this process is "array[i]", and the reference changes depending on the iteration.

[0015] For example, if i and j are different integers, then "array[i]" and "array[j]" will be stored in different areas of memory, as shown in Figure 1(b), and the references in memory will also change in the i-th and j-th iterations.

[0016] Therefore, even if the i-th and j-th iterations are executed in parallel on separate computing cores, the execution result will be the same as before parallelization. In this way, the loop in Figure 1(a) is a process that can be parallelized.

[0017] On the other hand, Figure 2(a) shows pseudocode for a loop that may not be parallelizable. In this example, the index of an array "array" is determined by the elements of another array "index". Suppose there are distinct integers i and j such that index[i]=index[j].

[0018] FIG. 2(b) is a schematic diagram showing the storage locations of the array elements “array[index[i]]” and “array[index[j]]” in memory 1 in this case.

[0019] As shown in Figure 2(b), in this case, the references "array[[index[i]]]" and "array[[index[j]]]" in the i-th and j-th iterations are the same. Therefore, if the i-th and j-th iterations are executed in parallel, the execution results may be different compared to when they are not parallelized.

[0020] If we execute the i-th and j-th iterations in this order, the operations will be executed in the following order: (1) Create a value x by adding 1 to array[index[i]]. (2) Store x in array[index[i]]. (3) Create a value y by adding 1 to array[index[j]]. (4) Store y in array[index[j]]. In this case, if the value of array[index[i]] = array[index[j]] before executing the loop is n, then the value of array[index[i]] = array[index[j]] after executing the loop will be n+2.

[0021] On the other hand, when executed in parallel, the processes may be executed in the following order: (1) Create a value x by adding 1 to array[index[i]]. (2) Create a value y by adding 1 to array[index[j]]. (3) Store x in array[index[i]]. (4) Store y in array[index[j]]. In this case, after executing the loop, the value of array[index[i]]=array[index[j]] will be incorrectly n+1.

[0022] Therefore, if memory references in different iterations overlap, such as when index[i]=index[j] for different i, j, the loop cannot be parallelized.

[0023] However, if index[i] and index[j] are different for all i and j, the memory references in different iterations do not overlap, and the loop can be parallelized. Therefore, it is preferable to determine whether to parallelize the loop depending on the memory references in different iterations, and to parallelize the loop if parallelization is possible to increase the execution speed of the program.

[0024] (First embodiment) FIG. 3 is a hardware configuration diagram of the compiler device according to this embodiment.

[0025] The compiler device 10 is a computer such as a virtual machine or a physical machine, and includes a storage device 10a, a memory 10b, a processor 10c, a communication interface 10d, an input device 10e, a display device 10f, and a media reader 10g. These components are connected to each other by a bus 10i.

[0026] Of these, the storage device 10a is a non-volatile storage such as a hard disk drive (HDD) or a solid state drive (SSD), and stores the compiler 11 according to this embodiment.

[0027] The compiler 11 may be recorded on a computer-readable recording medium 10h, and the compiler 11 may be read by the processor 10c via a medium reader 10g.

[0028] Examples of such recording media 10h include physically portable recording media such as CD-ROMs (Compact Disc - Read Only Memory), DVDs (Digital Versatile Discs), and USB (Universal Serial Bus) memories. Semiconductor memories such as flash memories and hard disk drives may also be used as the recording media 10h. These recording media 10h are not temporary media such as carrier waves that do not have a physical form.

[0029] Furthermore, the compiler 11 may be stored in a device connected to a public line, the Internet, a LAN (Local Area Network), etc. In that case, the processor 10c may read and execute the compiler 11.

[0030] On the other hand, the memory 10b is hardware that temporarily stores data, such as a dynamic random access memory (DRAM).

[0031] The processor 10c is a central processing unit (CPU) or a graphical processing unit (GPU) that controls each part of the compiler device 10. The processor 10c also executes the compiler 11 in cooperation with the memory 10b.

[0032] Furthermore, the communication interface 10d is hardware such as a network interface card (NIC) for connecting the compiler device 10 to a network such as the Internet or a local area network (LAN).

[0033] The input device 10e is hardware such as a mouse and a keyboard that allows a user to input various data to the compiler device 10. The display device 10f is hardware such as a liquid crystal display that displays the compilation results and errors that occur during compilation.

[0034] The medium reader 10g is hardware such as a CD drive, a DVD drive, or a USB interface for reading the recording medium 10h.

[0035] Fig. 4 is a schematic diagram showing the processing performed by the compiler device 10. As shown in Fig. 4, the compiler device 10 is a device that acquires a source program 12 and converts it into an executable program 13. The programming language in the source program 12 is not particularly limited, and the source program 12 may be written in, for example, C language, C++ language, or the like.

[0036] The executable program 13 is a binary file that is executable on a target machine, which may be, for example, a computer for HPC that is different from the compiler device 10.

[0037] 5 is a functional configuration diagram of the compiler device 10. As shown in FIG. 5, the compiler device 10 includes a communication unit 21, an input unit 22, a display unit 23, a control unit 24, and a storage unit 25.

[0038] The communication unit 21 is a processing unit for connecting the compiler device 10 to a network such as the Internet or a LAN, and is realized by the above-mentioned communication interface 10d.

[0039] The input unit 22 is a processing unit that allows a user to input various data to the compiler device 10, and is realized by the above-mentioned input device 10e.

[0040] The display unit 23 is a processing unit that displays the compilation result, errors that occur during compilation, and the like, and is realized by the above-mentioned display device 10f.

[0041] The storage unit 25 is realized by the storage device 10a and the memory 10b, and stores, for example, the intermediate code generated by the compiler device 10 and the like.

[0042] The control unit 24 is a processing unit that controls each unit of the compiler device 10. As an example, the control unit 24 includes an acquisition unit 31, an intermediate code generation unit 32, an optimized code generation unit 33, a machine code generation unit 34, and an output unit 35.

[0043] Of these, the acquisition unit 31 acquires the source program 12 to be compiled via the communication unit 21 and stores it in the storage unit 25 .

[0044] The intermediate code generation unit 32 is a processing unit that performs lexical analysis, syntactic analysis, and semantic analysis on the source program 12 to generate an intermediate code 41 that performs processing equivalent to that of the source program 12. The intermediate code 41 is an example of a first program. The intermediate code generation unit 32 stores the generated intermediate code 41 in the storage unit 25.

[0045] The optimized code generating unit 33 generates an optimized code 42, which is an intermediate code obtained by parallelizing a loop included in the intermediate code 41, and stores the optimized code 42 in the storage unit 25. The optimized code 42 is an example of a second program.

[0046] The machine code generator 34 converts the optimized code 42 into a machine code, and stores the executable program 13 including the machine code in the memory unit 25 .

[0047] The output unit 35 is a processing unit that outputs the executable program 13 stored in the storage unit 25 to the outside of the compiler device 10 via the communication unit 21 .

[0048] FIG. 6 is a flowchart of the compiling method according to this embodiment.

[0049] First, the acquisition unit 31 acquires the source program 12 (step S11), and the intermediate code generation unit 32 generates the intermediate code 41 of the source program 12 (step S12).

[0050] Next, the optimization code generating unit 33 performs an optimization process to generate the optimization code 42 (step S13).

[0051] Next, the machine code generator 34 generates the executable program 13 by converting the optimized code 42 into a machine code (step S14), and the output unit 35 outputs the executable program 13 (step S15).

[0052] This completes the basic processing of the compiling method according to this embodiment.

[0053] Next, the optimization process in step S13 will be described.

[0054] 7 is a flowchart of the optimization process. First, the optimized code generation unit 33 determines whether or not there is a dependency between iterations in the loop included in the intermediate code 41 that does not go through the memory 10b (step S21).

[0055] FIG. 8 is a schematic diagram of pseudocode obtained by converting the intermediate code 41 having a dependency between iterations that does not go through the memory 10b into source code.

[0056] In the example of Fig. 8, elements of the array "array" are added to the variable "sum" inside the loop using the for statement. In this case, the variable "sum" is assigned to a register in the processor 10c, and an area for storing the variable "sum" is not allocated in the memory 10b. Therefore, when i and j are different integers, there is no case where the reference destination of the memory 10b overlaps in the ith and jth iterations.

[0057] However, the (i+1)th iteration uses the variable "sum" that stores the result of the i-th iteration, so the execution result of the (i+1)th iteration changes depending on the execution result of the i-th iteration. In this way, even though the memory 10b is referenced by different iterations, when the execution result of one iteration changes depending on the execution result of the other iteration, it is said that there is a dependency between the iterations that does not go through the memory 10b.

[0058] 7 again, if the determination in step S21 is positive, in this embodiment, parallelization of the loop is abandoned, and the optimized code generator 33 generates optimized code 42 that does not include parallel processing in step S26.

[0059] On the other hand, if the determination in step S21 is negative, the process proceeds to step S22. In step S22, the optimized code generator 33 determines whether or not there is a dependency between iterations in the loop included in the intermediate code 41 via the memory 10b.

[0060] FIG. 9A is a schematic diagram of pseudocode obtained by converting intermediate code 41 having dependency between iterations via memory 10b into source code.

[0061] In the example of Figure 9(a), inside the loop using the for statement, 1 is added to the (i+1)th element of the array "array", "array[i+1]", and the result is stored in the i-th element, "array[i]".

[0062] FIG. 9B is a schematic diagram showing the elements "array[i]" and "array[i+1]" secured in the memory 10b.

[0063] In this example, the element "array[i+1]" is referenced in the i-th iteration of the loop, and a value is stored in the element "array[i+1]" in the i+1-th iteration. Therefore, the reference destination of memory 10b in the i-th and i+1-th iterations overlaps with the element "array[i+1]". When the reference destination of memory 10b in different iterations overlaps like this, it is said that there is a dependency between the iterations via memory 10b.

[0064] 7 again, if the determination in step S22 is negative, the process proceeds to step S25. In step S25, the optimization code generation unit 33 generates optimization code 42 including a parallelization process that parallelizes the loop included in the intermediate code 41.

[0065] Fig. 10(a) is a schematic diagram of pseudocode obtained by converting the intermediate code 41, which is the source of the optimized code 42, into source code. As shown in Fig. 10(a), in this loop, there is no dependency via the memory 10b between different iterations.

[0066] FIG. 10(b) is a schematic diagram of pseudocode obtained by converting the optimization code 42 generated from the loop in FIG. 10(a) into source code in step S25.

[0067] In the example of FIG. 10(b), the keyword "parallel" causes the process 51 inside the loop to be parallelized. The method of parallelization is not particularly limited. For example, different iterations i may be assigned to multiple computing cores of a CPU included in the target machine, and the process 51 may be performed by a different computing core for each iteration i. Also, if the CPU of the target machine is a vector processor, the process 51 may be parallelized by vectorization, which treats the array element "array[i]" as an element of a vector.

[0068] 7 again, if the determination in step S22 is affirmative, the process proceeds to step S23, in which the optimized code generation unit 33 determines whether the loop included in the intermediate code 41 has a dependency via another array.

[0069] FIG. 11(a) is a schematic diagram of pseudo code obtained by converting intermediate code 41 having a dependency via another array into source code.

[0070] 2(a), and has a loop 50 including an operation 53 for adding "1" to an element of the array "array." In addition, in the operation 53, the index "k" of the array "array" is determined by the element "index[i]" of another array "index" different from the array "array."

[0071] In this embodiment, when an index of an array inside a loop 50 is determined by elements of another array in this manner, the loop 50 is said to have a dependency via the other array. Also, it is assumed that the array used as the index cannot be rewritten during the loop.

[0072] 11(a), the array "index" is an example of a first array that uses the iteration "i" as an index, and the array "array" is an example of a second array that uses the element "index[i]" of the array "index" as an index.

[0073] FIG. 11B is a schematic diagram of the memory 10b to which the arrays "array" and "index" are allocated.

[0074] In FIG. 11(b), it is assumed that elements "index[i]" and "index[j]" of array "index" are different for different iterations "i" and "j". In this case, element "array[index[i]]" of array "array" is assigned to a first area 54 in memory 10b. Also, element "array[index[j]]" is assigned to a second area 55 that does not overlap with first area 54 in memory 10b.

[0075] Therefore, even if process 53 of iteration "i" and process 53 of iteration "j" are executed in parallel, the execution result of one process 53 does not change depending on the execution result of the other process 53, and iterations "i" and "j" can be executed in parallel.

[0076] In this example, iterations "i" and "j" are examples of the first and second execution times, respectively. Also, element "array[index[i]]" is an example of the first element, and element "array[index[j]]" is an example of the second element.

[0077] On the other hand, FIG. 11(c) is a schematic diagram of the memory 10b when parallel execution is not possible.

[0078] In this example, it is assumed that elements "index[i]" and "index[j]" of array "index" are the same for different iterations "i" and "j". In this case, the first area 54 and the second area 55 match, and the two overlap. Therefore, if process 53 of iteration "i" and process 53 of iteration "j" are executed in parallel, the execution result of one process 53 will change depending on the execution result of the other process 53, and the processes 53 cannot be executed in parallel.

[0079] In this way, when the loop 50 contained in the intermediate code 41 has a dependency via another array, the process 53 in the loop 50 may be parallelized in some cases (FIG. 11(b)) and may not be parallelized in other cases (FIG. 11(c)).

[0080] 7 again. If the determination in step S23 is positive, the optimization code generation unit 33 generates optimization code 42 based on the intermediate code 41 (step S24). As described above, in this case, the process 53 in the loop 50 may or may not be parallelizable. Therefore, the optimization code generation unit 33 generates, within the optimization code 42, code that parallelizes the process in the loop 50 and code that executes the process in sequence without parallelizing it.

[0081] FIG. 12 is a schematic diagram of pseudo code obtained by converting the optimization code 42 thus generated by the optimization code generating unit 33 into source code.

[0082] Here, an example will be described in which the optimized code generation unit 33 generates optimized code 42 from the intermediate code 41 in Fig. 11(a). In the following, the blocks of the for statement in the optimized code 42 are defined by indentation.

[0083] As shown in FIG. 12, the optimization code 42 has first to third codes 56 to 58.

[0084] Among these, the first code 56 is a code that defines a function "has_no_dupulicated_index()". The function "has_no_dupulicated_index()" is a function that judges whether the first and second regions 54, 55 (see FIG. 11(b)) referred to by the process 53 in each of the iterations "i" and "j" are duplicated for all combinations of "i" and "j". If it is found that the regions 54, 55 are duplicated for any combination of "i" and "j", the function "has_no_dupulicated_index()" returns "FALSE". If it is found that the regions 54, 55 are not duplicated for all combinations of "i" and "j", the function "has_no_dupulicated_index()" returns "TRUE".

[0085] In this example, the function "has_no_dupulicated_index()" determines whether the elements "index[i]" and "index[j]" in the statement "index[i]==index[j]" are the same, thereby determining whether the regions 54 and 55 are duplicated. The element "index[i]" is an example of a third element, and the element "index[j]" is an example of a fourth element.

[0086] Also, if the function "has_no_dupulicated_index()" returns "FALSE", the if statement in the first line causes the target machine to execute the second code 57.

[0087] The second code 57 is identical to the loop 50 (see FIG. 11(a)) of the original intermediate code 41 that has not been parallelized. Therefore, when the target machine executes the second code 57, the process 53 is executed in the order of iterations. Thus, in this embodiment, if the regions 54, 55 overlap in any combination of "i" and "j", the process 53 is not parallelized, and the target machine executes the second code 57 that executes the process 53 in the order of iterations.

[0088] On the other hand, if the function "has_no_dupulicated_index()" returns "TRUE", the if statement in the first line causes the target machine to execute the third code 58.

[0089] The third code 58 has a keyword "parallel" on the second line, which causes the target machine to execute each process 53 of iterations "i" and "j" in parallel. The parallelization method is not particularly limited, and for example, the process 53 may be parallelized by thread parallelism. In thread parallelism, parallelization is achieved by dividing the interval [0, N-1] into multiple small intervals and assigning each small interval to each of multiple calculation cores of the CPU of the target machine.

[0090] In this manner, in this embodiment, if the regions 54, 55 do not overlap for all combinations of "i" and "j", the target machine executes the third code 58 that executes the process 53 in parallel.

[0091] 7 again, if the determination in step S23 is negative, the process proceeds to step S26, in which the optimized code generator 33 generates, as the optimized code 42, only the second code that does not include parallel processing.

[0092] Thereafter, the above steps S21 to S26 are repeated for all loops included in the intermediate code, and then the process returns to the caller.

[0093] This completes the basic processing of the compiling method according to this embodiment.

[0094] According to the present embodiment described above, as shown in Fig. 12, the optimization code generating unit 33 generates the optimization code 42 including the first to third codes 56 to 58. In this optimization code 42, the first code 56 determines whether the areas 54, 55 in the memory 10b overlap. If it is determined that the areas 54, 55 do not overlap, the third code 58 executes the process 53 in parallel, thereby improving the execution speed of the executable program 13. On the other hand, if it is determined that the areas 54, 55 overlap, the second code 57 executes the process 53 in the order of iterations, thereby preventing the process 53 from being executed in parallel and resulting in a different execution result from the original loop 50.

[0095] Note that this embodiment is not limited to the above. For example, in the above, the process 53 is parallelized by thread parallelism in the third code 58, but if the CPU of the target machine is a vector processor, the parallelization may be performed by vectorization as follows.

[0096] FIG. 13 is a schematic diagram of pseudocode obtained by converting the optimization code 42 into source code when the process 53 is parallelized by vectorization.

[0097] As shown in FIG. 13, the optimization code 42 includes first to third codes 56 to 58 and a definition code 59.

[0098] The first code 56 is code that defines a function "has_no_dupulicated_index_vector (iter)". The function "has_no_dupulicated_index_vector (iter)" receives an integer argument "iter" and determines whether there is a combination of iterations "i" and "j" included in the interval between "iter" and "VL-1" in which "index[i]" and "index[j]" are the same. The variable "VL" is the length of a vector that can be calculated by the CPU of the target machine.

[0099] If there exists a combination of iterations "i" and "j" where "index[i]" and "index[j]" are identical, the function "has_no_dupulicated_index_vector(iter)" returns "FALSE". On the other hand, if "index[i]" and "index[j]" are different for all iterations "i" and "j", the function "has_no_dupulicated_index_vector(iter)" returns "TRUE".

[0100] On the other hand, definition code 59 is code that defines the function "calc_vectorizable_iteration()."

[0101] The function "calc_vectorizable_iteration()" executes the function "has_no_dupulicated_index_vector (iter)" for each subinterval when the interval [0, N-1] is divided into subintervals of length VL. Note that here, "N" is assumed to be divisible by "VL".

[0102] In this example, if there is a combination of iterations "i" and "j" included in a certain subinterval where "index[i]" and "index[j]" are the same, "FALSE" is stored in the array element "vectorizable[p]" corresponding to the integer "p" representing the subinterval. On the other hand, if "index[i]" and "index[j]" are not the same for any combination of iterations "i" and "j" included in the subinterval corresponding to the integer "p", "TRUE" is stored in the array element "vectorizable[p]".

[0103] In the example of Fig. 13, the value of the array element "vectorizable[i]" is evaluated in the if statement on the third line. Then, for the i-th subsection where the array element "vectorizable[i]" is "FALSE", the second code 57 is executed. The second code 57 is not a code that parallelizes the process 53, but a code that executes the process 53 in the order of iterations.

[0104] On the other hand, for the i-th small section in which the array element "vectorizable[i]" is "TRUE", the third code 58 is executed.

[0105] The third code 58 is code for executing a vector operation on the vector "array[k]" of the array elements. In this example, the third code 58 performs the process 53 in parallel for all iterations included in the i-th subinterval. The statement on the sixth line, "array[k] = array[k] + (1, 1, ..., 1)," indicates the process of adding the vector (1, 1, ..., 1) to the vector whose element is the array element "array[k]." This allows the process 53 to be performed in parallel for all iterations included in the i-th subinterval. Note that "index[i * VL : (i+1) * VL-1]" on the fifth line indicates the elements from "i * VL" to "(i+1) * VL-1" of the array "index."

[0106] FIG. 14 is a schematic diagram showing an example of the values ​​of the elements of the arrays "vectorizable" and "index" when the vector length "VL" is 2.

[0107] As shown in FIG. 14, if the elements of the array "index" are different, the value of the array "vectorizable" is "TRUE", and if the elements of the array "index" are the same, the value of the array "vectorizable" is "FALSE".

[0108] FIG. 15 is a flowchart showing the process when the target machine executes the first code 56 and the definition code 59 in FIG.

[0109] First, the target machine assigns "TRUE" to the array element "vectorizable[p]" (step S31).

[0110] Next, the target machine executes step S32 corresponding to the if statement on line 26. In step S32, the target machine determines whether the array element "index[i]" is equal to the array element "index[j]" for different "i" and "j." If the determination in step S32 is positive, the process proceeds to step S33, where the target machine assigns "FALSE" to the array element "vectorizable[p]."

[0111] If the determination in step S32 is negative or after step S33 is completed, the above steps S31 to S33 are repeated for each of "p", "i", and "j", and then the process is completed.

[0112] According to this, if the areas 54, 55 in the memory 10b do not overlap, the processes 53 can be executed in parallel in a target machine equipped with a vector processor, thereby improving the execution speed of the executable program 13.

[0113] Second embodiment In the first embodiment, the optimization code 42 shown in Fig. 12 is generated by the optimization code generation unit 33. In the optimization code 42, the if statement in the first line calls the function "has_no_dupulicated_index()". Therefore, when the target machine executes the executable program 13, the target machine always executes the first code 56 that defines the function "has_no_dupulicated_index()".

[0114] However, when the source program 12 calls the loop 50 (see FIG. 11(a)) multiple times, if the target machine always executes the first code 56 every time the loop is called, the execution speed of the executable program 13 will decrease.

[0115] Therefore, in this embodiment, the decrease in the execution speed of the executable program 13 is suppressed as follows.

[0116] FIG. 16 is a schematic diagram of pseudo code obtained by converting the optimization code 42 generated by the optimization code generating unit 33 into source code in this embodiment.

[0117] In FIG. 16, the same codes as in FIG. 12 are used to represent the same processes as those in FIG. 12, and the description thereof will be omitted below.

[0118] As shown in FIG. 16, in this embodiment, the optimized code generating unit 33 generates fourth to sixth codes 61 to 63 within the first code 56.

[0119] The first code 56 is a function that defines a function "has_no_dupulicated_index()" as in the first embodiment. However, the arguments of the function "has_no_dupulicated_index()" according to this embodiment are the start address "start_addr" and the end address "end_addr" in the memory 10b.

[0120] When the executable program 13 is executed, the address of the first element of the array "index", "&index[0]", is set as the start address "start_addr". Also, the address of the last element of the array "index", "&index[N-1]", is set as the end address "end_addr".

[0121] As described in the sixth code 63, the function "has_no_dupulicated_index()" returns the array element result[{start_addr, end_addr}] if the value of the array element "is_check_done[{start_addr, end_addr}]" is "TRUE."

[0122] The array element "is_check_done[{start_addr, end_addr}]" is an element that indicates whether the contents of the area of ​​memory 10b determined by the start address "start_addr" and the end address "end_addr" have been changed since the previous execution of loop 50. For example, if all the contents of array elements "index[0]" to "index[N-1]" have not been changed since the previous execution of loop 50, the value of the array element "is_check_done[{start_addr, end_addr}]" is "TRUE." On the other hand, if the contents of any of array elements "index[0]" to "index[N-1]" have been changed since the previous execution of loop 50, the value of the array element "is_check_done[{start_addr, end_addr}]" is "FALSE."

[0123] The array "is_check_done" is an associative array. Its element "{start_addr, end_addr}" is either "TRUE" or "FALSE" corresponding to the pair "start_addr" and "end_addr". If neither "TRUE" nor "FALSE" corresponds to the pair "start_addr" and "end_addr", the value of "is_check_done[{start_addr, end_addr}]" is set to "FALSE". Such an associative array can be implemented, for example, using a hash table.

[0124] Furthermore, the array element result[{start_addr, end_addr}] stores the result of the judgment made the previous time loop 50 was executed. As shown in the if statement on line 17, the result of the judgment is whether or not there are any addresses with the same contents "*i" and "*j" among the different addresses "i" and "j" between the start address "start_addr" and the end address "end_addr".

[0125] Note that "*i" indicates the content stored at address "i". For example, if "i" is "&index[0]", then "*i" becomes "index[0]". The same applies to "*j". Therefore, the if statement on line 17 shows the same processing as the code on line 14 of FIG. 12, and is code that determines whether there are mutually different "i" and "j" in the range from 0 to N-1 such that "index[i]" and "index[j]" are equal.

[0126] Furthermore, the sixth code 63 returns a return value on line 13 when the value of the array element result[{start_addr, end_addr}] is "TRUE," and skips lines 14 and onward. As a result, when the value of the array element result[{start_addr, end_addr}] is "TRUE," the judgment of the if statement on line 17 is skipped, speeding up processing.

[0127] The fourth code 61 is code that saves the result of the judgment of the if statement on line 17, and includes code 61a and code 61b. Of these, code 61a is code that saves "TRUE" as an initial value in the array element result[{start_addr, end_addr}]. Code 61b is code that saves "FALSE" in the array element result[{start_addr, end_addr}] when the conditional expression of the if statement on line 17 is true.

[0128] Once the judgment by the if statement on line 17 is completed, the code on line 19 is executed and "TRUE" is stored in the array element "is_check_done[{start_addr, end_addr}]".

[0129] The if statement on line 20 is a statement that determines whether an area in memory 10b overlaps with the address range of the start address "start_addr" and the end address "end_addr", and whether that area has an element of the array "is_check_done" that is "TRUE". If the determination is positive, "FALSE" is stored in the element of the array "is_check_done" that corresponds to that area on line 21, and the watchpoint function for that area is released. The watchpoint function is a function that detects whether the contents of memory 10b in a specified address range have changed, and is a function possessed by the CPU of the target machine.

[0130] Then, in the fifth code 62 on line 22, the function "set_watchpoint()" is called.

[0131] The function "set_watchpoint()" receives a start address "start_addr", an end address "end_addr", and a function "disable_result()" as arguments, and sets the CPU to call "disable_result()" when the contents of these address ranges change. There are no particular limitations on how the function "set_watchpoint()" is realized. In this embodiment, the function "set_watchpoint()" is realized by using a watchpoint function provided in the CPU of the target machine.

[0132] As described above, when the executable program 13 is executed, the start address "start_addr" and the end address "end_addr" are equal to "&index[0]" and "&index[N-1]", respectively. Therefore, the function "set_watchpoint()" is set to detect whether the contents of any of the array elements "index[0]" to "index[N-1]" have been changed.

[0133] If a change in content is detected, the function "disable_result()" is called.

[0134] Then, on line 23, the array element result[{start_addr, end_addr}] is returned as the return value of the function "has_no_dupulicated_index()".

[0135] The function "disable_result()" in the fifth code 62 is an exception handler, and is defined in lines 26 to 30. Here, in line 27, the start address and end address of the address range whose contents have been changed are stored in the variables "start_addr" and "end_addr", respectively. This address range information is provided by the watchpoint function.

[0136] Also, on line 28, "FALSE" is stored in the array element "is_check_done[{start_addr, end_addr}]" that corresponds to the address range set on line 27.

[0137] Then, the function "unset_watchpoint()" is called on line 29. The function "unset_watchpoint()" receives the start address "start_addr" and the end address "end_addr" as arguments, and disables the watchpoint function that detects changes in the contents of this address range.

[0138] 17 and 18 are flowcharts showing a process when the target machine executes the first code 56 in the optimized code 42 in FIG.

[0139] First, the target machine sets the addresses of the array elements "index[0]" and "index[N-1]" as arguments to the function "has_no_dupulicated_index()" (step S41).

[0140] Next, the target machine executes the if statement on the 12th line to determine whether the value of the array element "is_check_done[{start_addr, end_addr}]" is "TRUE" (step S42).

[0141] If this determination is positive, the target machine executes line 13 to return the array element result[{start_addr, end_addr}] (step S50), and the process ends.

[0142] On the other hand, if the determination in step S42 is negative, the process proceeds to step S43.

[0143] In step S43, the target machine executes the code 61a to store "TRUE" in the array element result[{start_addr, end_addr}].

[0144] Next, the target machine executes the if statement on line 17 and determines whether there are any mutually distinct addresses "i" and "j" between the start address "start_addr" and the end address "end_addr" whose contents "*i" and "*j" are identical (step S44).

[0145] This determination is performed for all combinations of addresses "i" and "j" in the address range between the start address "start_addr" and the end address "end_addr".

[0146] If the determination in step S44 is positive, the target machine executes code 61b to store "FALSE" in the array element result[{start_addr, end_addr}] (step S45).

[0147] Next, the target machine executes line 19, thereby storing "TRUE" in the array element "is_check_done[{start_addr, end_addr}]" (step S46).

[0148] Next, the target machine executes the if statement on line 20 to determine whether any area that overlaps with the address range between "start_addr" and "end_addr" has an element of the array "is_check_done" that is "TRUE" (step S47).

[0149] If this determination is positive, the target machine executes line 21 to store "FALSE" in the element of the array "is_check_done" corresponding to the area, and disables the watchpoint function for the area (step S48).

[0150] On the other hand, if the determination in step S47 is negative, the process proceeds to step S49. In step S49, the target machine executes the fifth code 62 on the 22nd line to enable the watchpoint function.

[0151] Thereafter, the target machine executes line 23 to return the array element result[{start_addr, end_addr}] (step S50), and the process ends.

[0152] According to the present embodiment described above, when the target machine calls loop 50 multiple times, if the array elements “index[0]” to “index[N-1]” have not changed since the previous call, the judgment of the if statement in step S17 is skipped.

[0153] Therefore, for example, if the array elements "index[0]" to "index[N-1]" are not changed in the first call of loop 50, the if statement in step S17 is skipped in the subsequent second call of loop 50, thereby improving the execution speed of the program. [Explanation of symbols]

[0154] 1...memory, 10...compiler device, 11...compiler, 12...source program, 13...executable program, 21...communication unit, 22...input unit, 23...display unit, 24...control unit, 25...memory unit, 31...acquisition unit, 32...intermediate code generation unit, 33...optimized code generation unit, 34...machine language generation unit, 35...output unit, 36...output unit, 41...intermediate code, 42...optimized code, 50...loop, 51...processing, 53...processing, 54...first area, 55...second area, 56...first code, 57...second code, 58...third code, 59...definition code, 61...fourth code, 61a, 61b...code, 62...fifth code, 63...sixth code.

Claims

1. a first code for determining whether a first area of ​​memory that is referenced by a process inside a loop included in a first program in a first execution of the loop overlaps with a second area of ​​the memory that is referenced by the process in a second execution of the loop; a second code for executing the process in the order of the first execution time and the second execution time when it is determined that the first area and the second area overlap; a third code for executing the processes of the first execution round and the second execution round in parallel when it is determined that the first area and the second area do not overlap; generating a second program including The loop comprises: a first array indexed by the number of times the loop is executed; a second array having each element of the first array as an index; the process is a process of storing a first element of the second array in the memory in the first execution round, and storing a second element of the second array in the memory in the second execution round, the first area is an area in which the first element is stored in the first execution round, The second area is an area in which the second element is stored in the second execution round. A compiler that allows a computer to carry out processing.

2. The first program calls the loop multiple times; The second program is a fourth code for storing a result of the determination during a first of the multiple invocations; fifth code for detecting, after storing the results, whether the contents of any of the elements of the first array have been modified; a sixth code for skipping the determination of whether the first region and the second region overlap when a second call is made after the first call among the multiple calls if the content of the element has not been changed; 2. The compiler of claim 1, comprising:

3. The first code includes:

2. The compiler according to claim 1, further comprising code for determining that the first area and the second area overlap when a third element of the first array indexed by the first execution round and a fourth element of the first array indexed by the second execution round are identical, and determining that the first area and the second area do not overlap when the third element and the fourth element are not identical.

4. 2. The compiler according to claim 1, wherein the third code is code for executing a vector operation on a vector having the first element and the second element as elements.

5. a first code for determining whether a first area of ​​memory that is referenced by a process inside a loop included in a first program in a first execution of the loop overlaps with a second area of ​​the memory that is referenced by the process in a second execution of the loop; a second code for executing the process in the order of the first execution time and the second execution time when it is determined that the first area and the second area overlap; a third code for executing the processes of the first execution round and the second execution round in parallel when it is determined that the first area and the second area do not overlap; A second program is generated by the computer, the second program including The loop comprises: a first array indexed by the number of times the loop is executed; a second array having each element of the first array as an index; the process is a process of storing a first element of the second array in the memory in the first execution round, and storing a second element of the second array in the memory in the second execution round, the first area is an area in which the first element is stored in the first execution round, The second area is an area in which the second element is stored in the second execution round. A compilation method comprising:

6. a first code for determining whether a first area of ​​memory that is referenced by a process inside a loop included in a first program in a first execution of the loop overlaps with a second area of ​​the memory that is referenced by the process in a second execution of the loop; a second code for executing the process in the order of the first execution time and the second execution time when it is determined that the first area and the second area overlap; a third code for executing the processes of the first execution round and the second execution round in parallel when it is determined that the first area and the second area do not overlap; A generator that generates a second program including: The loop comprises: a first array indexed by the number of times the loop is executed; a second array having each element of the first array as an index; the process is a process of storing a first element of the second array in the memory in the first execution round, and storing a second element of the second array in the memory in the second execution round, the first area is an area in which the first element is stored in the first execution round, The second area is an area in which the second element is stored in the second execution round. A compiler apparatus comprising:

Citation Information

Patent Citations

  • Language processor, computer and medium recording program

    JP1998333919A

  • Method and device for parallelized complication

    JP1999203256A

  • Dynamic vectorization device and record medium

    JP1999272650A

  • Execution module optimization device, execution module optimization method and program

    JP2013242604A