Patent Description:
A single instruction, multiple data (SIMD) processing system is a class of parallel computing systems that includes multiple processing elements which execute the same instruction on multiple pieces of data. A SIMD system may be a standalone computer or a sub-system of a computing system. For example, one or more SIMD execution units may be used in a graphics processing unit (GPU) to implement a programmable shading unit that supports programmable shading. A SIMD processing system allows multiple threads of execution for a program to execute synchronously on the multiple processing elements in a parallel manner, thereby increasing the throughput for programs where the same set of operations needs to be performed on multiple pieces of data. A particular instruction executing on a particular SIMD processing element is referred to as a thread or a fiber. A group of threads may be referred to as a wave or warp.

Processing units, such as GPUs, include processing elements and a general purpose register (GPR) that stores data for the execution of an instruction. In some examples, a processing element executes instructions for processing one item of data, and respective processing elements store the data of the item or the resulting data of the item from the processing in the GPR. An item of data may be the base unit on which processing occurs. For instance, in graphics processing, a vertex of a primitive is one example of an item, and a pixel is another example of an item. There is graphics data associated with each vertex and pixel (e.g., coordinates, color values, etc.).

There may be multiple processing elements within a processor core of the processing element allowing for parallel execution of an instruction (e.g., multiple processing elements execute the same instruction at the same time). A shader is a computer program that can utilize a parallel processing environment (e.g., shader processors) and have been used to perform graphics rendering techniques on two and three-dimensional models at various stages of the graphics processing pipeline. Examples of shaders include pixel (or fragment) shaders, used to compute color and other attributes of a pixel (or fragment); vertex shaders, used to control position, movement, lighting, and color, or a vertex; geometry shaders, used to generate graphics primitives; tessellation-related shaders (e.g., hull shaders and/or domain shaders that are used when subdividing patches of vertex data into smaller primitives; and compute shaders are used for computing other information (e.g., non-graphics data).

<CIT> describes a method of operating a graphics processing system and a graphics processing system for operating the method, in which expressions of a shader program that operate on run time constant inputs are identified and a new shader program is created containing instructions for the identified expressions. The original shader program is modified to replace the identified expressions with load instructions pointing to the output data of the new shader program. The new shader program is executed to generate and store output values for the identified expressions, and once this execution has completed, the modified shader program is executed, loading output values from the new shader program in accordance with the new load instructions.

In general, the disclosure describes techniques for reducing redundant operations when executing a shader program on a shader processor of a GPU. In one example, this disclosure describes techniques whereby instructions that produce the same result among all parallel processing elements (e.g., threads) of a shader are identified and scheduled to execute once per shader and/or per command (e.g. a draw or dispatch command). A compiler may identify the redundant instructions and groups the redundant instructions into a code block called a per-shader preamble. The GPU system then executes the per-shader preamble once and saves the results of the redundant instructions of the per-shader preamble in on-chip memory. Each subsequent thread of the shader executing on the processing elements of the shader processor can then reuse the results without computing the same results again. Furthermore, data may be preloaded from system memory into on-chip random access memory (RAM) and/or on-chip state cache/buffer via the per-shader preamble.

In one example of this disclosure, there is provided a method of operating a graphic processing unit as defined in claim <NUM>. Preferred or optional features are defined in dependent claims <NUM> to <NUM>.

In another example, an apparatus for processing data is defined in claim <NUM>, with preferred or optional features set out in dependent claims <NUM> to <NUM>.

In another example, a non-transitory computer-readable storage medium including instructions stored thereon is defined in claim <NUM>.

Parallel processing units, such as graphics processing unit (GPUs) that are configured to perform many operations in parallel (e.g., at the same time or substantially the same time), include one or more processor cores (e.g., shader cores for a GPU) that execute instructions of one or more programs. For ease of description, the techniques described in the disclosure are described with respect to a GPU configured to perform graphics processing applications and/or general purpose GPU (GPGPU) applications. However, the techniques described in this disclosure may be extended to parallel processing units that are not necessarily GPUs or GPGPUs, as well as non-parallel processing units (e.g., ones not specifically configured for parallel processing).

The GPU may be designed with a single instruction, multiple data (SIMD) structure. In the SIMD structure, a shader core (or more generally a SIMD processing core) includes a plurality of SIMD processing elements, where each SIMD processing element executes instructions of the same program, but on different data. A particular instruction executing on a particular SIMD processing element is referred to as a thread or a fiber. A group of threads may be referred to as a wave or warp. All of the processing elements together that execute a warp may be referred to as a vector processing unit, where each lane (e.g., processing element) of the vector executes one thread. Each SIMD processing element may be considered as executing a different thread because the data for a given thread may be different; however, the thread executing on a processing element is the same instruction, of the same program, as the instruction executing on the other processing elements. In this way, the SIMD structure allows the GPU to perform many tasks in parallel (e.g., at the same time).

A shader (or shader program) is a computer program that can utilize a parallel processing environment (e.g., shader processors). A draw command refers to one or more of a family of commands executed by a processing unit (e.g. a CPU) to a graphics application program interface (API) which interacts with a graphical processing unit (e.g. GPU) to draw (e.g. render) an object for display on a display device. A dispatch command refers to a one or more of a family of commands executed by a processing unit (e.g. a CPU) to a graphics API which interacts with a graphics processing unit (GPU) to execute non-display operations. Elements of a draw or dispatch command may execute redundant operations in an associated shader. In particular, a GPU may perform batch processing commands such as draw calls and dispatches. A command may instruct the GPU to use one or more shaders to process elements such as work items, pixels, and vertices. A shader may then be invoked for the element. The same shader may be invoked for the command's elements of the same type. An operation of the shader may produce the same result for all elements of the same type. Such operations may be identified and executed a single time without the need to redundantly execute the same code segment for each element.

This disclosure describes methods, techniques, and devices whereby operations of a shader that produce the same result for all elements of the same type are identified and scheduled to execute once per shader type and/or per command (e.g. a draw or dispatch command). A compiler may identify the redundant instructions and groups the redundant instructions into a code block called a per-shader preamble. The GPU may execute the per-shader preamble once and saves the results of the redundant instructions of the per-shader preamble in on-chip memory (e.g., random access memory (RAM)). The redundant instructions may allow for the use of a read/write constant RAM and the constants used in the calculations of the redundant instructions may be loaded into this read/write constant RAM prior to the execution of the redundant instructions (i.e., the per-shader preamble). The elements of the shader can reuse the results without computing the same results again. This may significantly improve performance and reduce power consumption.

<FIG> is a block diagram illustrating an example device for processing data in accordance with one or more example techniques described in this disclosure for the generation and execution of per-shader preambles. <FIG> illustrates device <NUM>, examples of which include, but are not limited to, video devices such as media players, set-top boxes, wireless communication devices, such as mobile telephones, personal digital assistants (PDAs), desktop computers, laptop computers, gaming consoles, video conferencing units, tablet computing devices, and the like.

In the example of <FIG>, device <NUM> includes processor <NUM>, graphics processing unit (GPU) <NUM>, and system memory <NUM>. In some examples, such as examples where device <NUM> is a mobile device, processor <NUM> and GPU <NUM> may be formed as an integrated circuit (IC). For example, the IC may be considered as a processing chip within a chip package, such as a system on chip (SoC). In some examples, processor <NUM> and GPU <NUM> may be housed in different integrated circuits (e.g., different chip packages) such as examples where device <NUM> is a desktop or laptop computer. However, it may be possible that processor <NUM> and GPU <NUM> are housed in different integrated circuits in examples where device <NUM> is a mobile device.

Examples of processor <NUM> and GPU <NUM> include, but are not limited to, one or more digital signal processors (DSPs), general purpose microprocessors, application specific integrated circuits (ASICs), field programmable logic arrays (FPGAs), or other equivalent integrated or discrete logic circuitry. Processor <NUM> may be the central processing unit (CPU) of device <NUM>. In some examples, GPU <NUM> may be specialized hardware that includes integrated and/or discrete logic circuitry that provides GPU <NUM> with massive parallel processing capabilities suitable for graphics processing (e.g., a SIMD processor). In some instances, GPU <NUM> may also include general purpose processing capabilities, and may be referred to as a general purpose GPU (GPGPU) when implementing general purpose processing tasks (i.e., non-graphics related tasks).

For purposes of illustration, the techniques described in this disclosure are described with GPU <NUM>. However, the techniques described in this disclosure are not so limited. The techniques described in this disclosure may be extended to other types of parallel processing units (e.g., processing units that provide massive parallel processing capabilities, even if not for graphics processing). Also, the techniques described in this disclosure may be extended to processing units not specifically configured for parallel processing.

Processor <NUM> may execute various types of applications. Examples of the applications include operating systems, web browsers, e-mail applications, spreadsheets, video games, or other applications that generate viewable objects for display. System memory <NUM> may store instructions for execution of the one or more applications. The execution of an application on processor <NUM> causes processor <NUM> to produce graphics data for image content that is to be displayed. Processor <NUM> may transmit graphics data of the image content to GPU <NUM> for further processing.

As an example, the execution of an application on processor <NUM> causes processor <NUM> to produce vertices of primitives, where the interconnection of primitives at respective vertices forms a graphical object. In this example, the graphics data that processor <NUM> produces are the attribute data for the attributes of the vertices. For example, the application executing on processor <NUM> may generate color values, opacity values, coordinates, etc. for the vertices, which are all examples of attributes of the vertices. Some of the attributes of the vertices may be generated using, in part, code that would be replicated for each vertex, particularly where such code, once executed, evaluates to a constant. Processor <NUM> may then execute the identified redundant code a single time (e.g., during the execution for the first vertex) and reuse that result for the rest of the vertices that utilize such redundant code. In general, the techniques are extendable to data types (e.g., counters) other than attribute data, and the techniques should not be considered limited to attribute data or limited to examples of attribute data such as color values, opacity values, coordinates, etc..

In some non-graphics related examples, processor <NUM> may generate data that is better suited to be processed by GPU <NUM>. Such data need not be for graphics or display purposes. For instance, processor <NUM> may output data on which matrix operations need to be performed by GPU <NUM>, and GPU <NUM> may in turn perform the matrix operations.

In general, processor <NUM> may offload processing tasks to GPU <NUM>, such as tasks that require massive parallel operations. As one example, graphics processing requires massive parallel operations, and processor <NUM> may offload such graphics processing tasks to GPU <NUM>. However, other operations such as matrix operations may also benefit from the parallel processing capabilities of GPU <NUM>. In these examples, processor <NUM> may leverage the parallel processing capabilities of GPU <NUM> to cause GPU <NUM> to perform non-graphics related operations.

Processor <NUM> may communicate with GPU <NUM> in accordance with a particular application processing interface (API). Examples of such APIs include the DirectX® API by Microsoft®, the OpenGL® or OpenGL ES® by the Khronos group, and the OpenCL™; however, aspects of this disclosure are not limited to the DirectX, the OpenGL, or the OpenCL APIs, and may be extended to other types of APIs. Moreover, the techniques described in this disclosure are not required to function in accordance with an API and processor <NUM> and GPU <NUM> may utilize any technique for communication.

Device <NUM> may also include display <NUM>, user interface <NUM>, and transceiver module <NUM>. Device <NUM> may include additional modules or units not shown in <FIG> for purposes of clarity. For example, device <NUM> may include a speaker and a microphone, neither of which are shown in <FIG>, to effectuate telephonic communications in examples where device <NUM> is a mobile wireless telephone. Furthermore, the various modules and units shown in device <NUM> may not be necessary in every example of device <NUM>. For example, user interface <NUM> and display <NUM> may be external to device <NUM> in examples where device <NUM> is a desktop computer. As another example, user interface <NUM> may be part of display <NUM> in examples where display <NUM> is a touch-sensitive or presence-sensitive display of a mobile device.

Display <NUM> may comprise a liquid crystal display (LCD), a cathode ray tube (CRT) display, a plasma display, a touch-sensitive display, a presence-sensitive display, or another type of display device. Examples of user interface <NUM> include, but are not limited to, a trackball, a mouse, a keyboard, and other types of input devices. User interface <NUM> may also be a touch screen and may be incorporated as a part of display <NUM>. Transceiver module <NUM> may include circuitry to allow wireless or wired communication between device <NUM> and another device or a network. Transceiver module <NUM> may include modulators, demodulators, amplifiers and other such circuitry for wired or wireless communication.

System memory <NUM> may be the memory for device <NUM>. System memory <NUM> may comprise one or more computer-readable storage media. Examples of system memory <NUM> include, but are not limited to, a random access memory (RAM), an electrically erasable programmable read-only memory (EEPROM), flash memory, or other medium that can be used to carry or store desired program code in the form of instructions and/or data structures and that can be accessed by a computer or a processor.

In some aspects, system memory <NUM> may include instructions that cause processor <NUM> and/or GPU <NUM> to perform the functions ascribed in this disclosure to processor <NUM> and GPU <NUM>. Accordingly, system memory <NUM> may be a computer-readable storage medium having instructions stored thereon that, when executed, cause one or more processors (e.g., processor <NUM> and GPU <NUM>) to perform various functions.

In some examples, system memory <NUM> may be a non-transitory storage medium. The term "non-transitory" may indicate that the storage medium is not embodied in a carrier wave or a propagated signal. However, the term "non-transitory" should not be interpreted to mean that system memory <NUM> is non-movable or that its contents are static. As one example, system memory <NUM> may be removed from device <NUM>, and moved to another device. As another example, memory, substantially similar to system memory <NUM>, may be inserted into device <NUM>. In certain examples, a non-transitory storage medium may store data that can, over time, change (e.g., in RAM).

For example, as described in more detail elsewhere in this disclosure, system memory <NUM> may store the code for a compiler that executes on processor <NUM> that performs techniques of one or more examples described in this disclosure. System memory <NUM> may also store code for shader programs (e.g., a vertex shader, a pixel or fragment shader, tessellation-related shaders, a compute shader, etc.) that execute on a shader core (also referred to as a shader processor or kernel) of GPU <NUM>. Furthermore, system memory <NUM> may store one or more constant buffers. Constant load instructions may allow compiler <NUM> to load constants from system memory into a constant memory <NUM> of GPU <NUM>. Constants may be loaded into GPRs <NUM> (or uGPRs <NUM>) if constant memory <NUM> is full.

The term graphics item is used in this disclosure to refer to a base unit on which GPU <NUM> performs parallel processing. GPU <NUM> may process a plurality of graphics items in parallel (e.g., at the same time). For example, a vertex shader may process a vertex, and GPU <NUM> may execute a plurality of instances of the vertex shader in parallel to process a plurality of vertices at the same time. Similarly, a pixel or fragment shader may process a pixel of a display, and GPU <NUM> may execute a plurality of instances of the pixel shader in parallel to process a plurality of pixels of the display at the same time. A vertex and a pixel are examples of a graphics item. For non-graphics related applications, the term "work item" may refer to smallest unit on which GPU <NUM> performs processing.

As will be explained in more detail below, according to various examples of the disclosure, GPU <NUM> may be configured to receive an indication (e.g., in a per-shader preamble) that all threads of a warp (or over multiple warps) in the GPU <NUM> are to execute a first set of instructions that are common between each thread (over a single or multiple warps) during the execution of the first thread/warp that were identified by a compiler executed by processor <NUM>. The instructions in the per-shader preamble may have been identified for inclusion in the per-shader preamble because the instructions use non-divergent inputs (e.g., they are scalar and/or uniform across all fibers/threads) that may be constant and/or variable/dynamic. GPU <NUM> may then access those constants from system memory <NUM> and store them in constants RAM on GPU <NUM>. When executing the common instructions of the per-shader preamble, GPU <NUM> may access the constants in the constant RAM. GPU <NUM> may perform the common instructions. After performing the common instructions of the per-shader preamble, GPU <NUM> may store the results in a read/write constant RAM. In another example, the results (e.g. constant values) of the per-shader preamble may be stored in one or more general purpose registers (GPR), uniform GPRs (uGPRs), or shared GPRs (sGPRs), in other on-chip RAM on GPU <NUM> or on system memory <NUM>. However, GPRs, uGPRs, and sGPRs may be cleared between each warp (i.e., data cannot be shared in GPRs between warps) and such data must be rewritten into such GPRs per warp. GPRs may also store data for (and be accessible by) a specific thread/fiber whereas uGPRs may store data for (and be accessible by) all threads/fibers in a wave/warp. Data may also be stored in system memory <NUM> or on-chip (e.g., on GPU <NUM>) memory that permits inter-warp data sharing. The results of the execution of the per-shader preamble may be reused for each element (e.g., thread) of the shader without reproducing the same results a second (or greater) time. The results of the execution of the per-shader preamble may also be reused for multiple warps of the shader without reproducing the same results a second (or greater) time.

<FIG> is a block diagram illustrating components of the device illustrated in <FIG> in greater detail. As illustrated in <FIG>, GPU <NUM> includes shader core <NUM>, which includes a general purpose register (GPR) <NUM>, uniform GPR <NUM>, and constant memory <NUM>, fixed-function pipeline(s) <NUM>, and GPU Memory <NUM>. GPR <NUM> may include a single GPR, a GPR file, and/or a GPR bank. uGPR <NUM> may include a single uGPR, a uGPR file, and/or a uGPR bank. GPR <NUM> may store data accessible to a single thread/fiber. uGPR <NUM> may store data accessible by all threads/fibers in a single wave/warp. Shader core <NUM> and fixed-function pipeline(s) <NUM> may together form a processing pipeline used to perform graphics or non-graphics related functions. The processing pipeline performs functions as defined by software or firmware executing on GPU <NUM> and performs functions by fixed-function units that are hardwired to perform specific functions. Such fixed-function pipelines <NUM> of GPU <NUM> may include a texture pipeline, a tessellation stage, clipping that fall outside the viewing frustum, and lighting.

The software and/or firmware executing on GPU <NUM> may be referred to as shader programs (or simply shaders), and the shader programs may execute on shader core <NUM> of GPU <NUM>. Although only one shader core <NUM> is illustrated, in some examples, GPU <NUM> may include two or more shader cores similar to shader core <NUM>. Fixed-function pipeline(s) <NUM> includes the fixed-function units. Shader core <NUM> and fixed-function pipeline(s) <NUM> may transmit and receive data from one another. For instance, the processing pipeline may include shader programs executing on shader core <NUM> that receive data from a fixed-function unit of fixed-function pipeline <NUM> and output processed data to another fixed-function unit of fixed-function pipeline <NUM>.

Shader programs provide users and/or developers with functional flexibility because a user can design the shader program to perform desired tasks in any conceivable manner. The fixed-function units, however, are hardwired for the manner in which the fixed-function units perform tasks. Accordingly, the fixed-function units may not provide much functional flexibility.

Examples of the shader programs include vertex shader program <NUM>, fragment shader program <NUM>, and compute shader program <NUM>. Vertex shader program <NUM> and fragment shader program <NUM> may be shader programs for graphics related tasks, and compute shader program <NUM> may be a shader program for a non-graphics related task. There are additional examples of shader programs such as geometry shaders and tessellation-related shaders, which are not described for purposes of brevity.

Graphics driver <NUM> executing on processor <NUM> may be configured to implement an application programming interface (API); although graphics driver <NUM> does not need to be limited to being configured in accordance with a particular API. In such examples, the shader programs (e.g., vertex shader program <NUM>, fragment shader program <NUM>, and compute shader program <NUM>) may be configured in accordance with an API supported by graphics driver <NUM>. In an example where device <NUM> is a mobile device, graphics driver <NUM> may be configured in accordance with the OpenGL ES API. The OpenGL ES API is specifically designed for mobile devices. In an example where device <NUM> is a non-mobile device, graphics driver <NUM> may be configured in accordance with the OpenGL API. Other API examples include the DirectX family of APIs by the Microsoft Corporation. Although not illustrated, system memory <NUM> may store the code for graphics driver <NUM> that processor <NUM> retrieves from system memory <NUM> for execution. Graphics driver <NUM> is illustrated in a dashed box to indicate that graphics driver <NUM> is software, executing on hardware (e.g., processor <NUM>), in this example.

Graphics driver <NUM> may be configured to allow processor <NUM> and GPU <NUM> to communicate with one another. For instance, when processor <NUM> offloads graphics or non-graphics processing tasks to GPU <NUM>, processor <NUM> offloads such processing tasks to GPU <NUM> via graphics driver <NUM>.

As an example, processor <NUM> may execute a gaming application that produces graphics data, and processor <NUM> may offload the processing of this graphics data to GPU <NUM>. In this example, processor <NUM> may store the graphics data in system memory <NUM>, and graphics driver <NUM> may instruct GPU <NUM> with when to retrieve the graphics data, from where to retrieve the graphics data in system memory <NUM>, and when to process the graphics data. Also, the gaming application may require GPU <NUM> to execute one or more shader programs. For instance, the gaming application may require shader core <NUM> to execute vertex shader program <NUM> and fragment shader program <NUM> to generate images that are to be displayed (e.g., on display <NUM> of <FIG>). Graphics driver <NUM> may instruct GPU <NUM> when to execute the shader programs and instruct GPU <NUM> with where to retrieve the graphics data needed for the shader programs. In this way, graphics driver <NUM> may form the link between processor <NUM> and GPU <NUM>.

In some examples, system memory <NUM> may store the source code for one or more of vertex shader program <NUM>, fragment shader program <NUM>, and compute shader program <NUM>. In these examples, compiler <NUM> executing on processor <NUM> may compile the source code of these shader programs to create object or intermediate code executable by shader core <NUM> of GPU <NUM> during runtime (e.g., at the time when these shader programs are to be executed on shader core <NUM>). In some examples, compiler <NUM> may pre-compile the shader programs and store the object or intermediate code of the shader programs in system memory <NUM>.

In accordance with the techniques of this disclosure, compiler <NUM> (or in another example graphics driver <NUM>) running on processor <NUM> may build a shader into multiple components including a "main" shader component and a "preamble" shader component. The main shader component may refer to a portion or the entirety of the shader program that does not include the preamble shader component. Compiler <NUM> may receive code to compile from a program executing on processor <NUM>. Compiler <NUM> may also identify constant load instructions and common operations in the shader and position the common operations within the preamble shader component (rather than the main shader component). Compiler <NUM> may identify these common instructions, for example, by an exclusive use of constants (i.e., constant values) in the common instructions. Compiler <NUM> may utilize instructions such as a shader preamble start to mark the beginning of the shader preamble and shader preamble end to mark the end of the shader preamble. Compiler <NUM> may utilize a SHPS (shader preamble start) instruction to mark the beginning of the per-shader preamble. MAIN is an exemplary label that the SHPS instruction may branch to if the current wave is not the first wave (e.g., to a main shader block of code). Compiler <NUM> may utilize a SHPE (shader preamble end) instruction to mark the end of the per-shader preamble.

Shader core <NUM> may be configured to execute many instances of the same instructions of the same shader program in parallel. For example, graphics driver <NUM> may instruct GPU <NUM> to retrieve vertex values for a plurality of vertices, and instruct GPU <NUM> to execute vertex shader program <NUM> to process the vertex values of the vertices. In this example, shader core <NUM> may execute multiple instances of vertex shader program <NUM>, and do so by executing one instance of vertex shader program <NUM> on one processing element of shader core <NUM> for each of the vertices.

During the processing of a first wave of the execution of a shader program <NUM>, <NUM>, or <NUM> on shader core <NUM>, shader core <NUM> may execute the shader preamble. Constant inputs used in the execution of the shader preamble may be stored in a read/write constant memory <NUM> (e.g., constant RAM), GPRs (e.g., GPR <NUM>), or uGPRs (e.g. uGPR <NUM>). A load unit of shader core <NUM> may load the constants into constant memory <NUM>. Instructions to the load unit of shader core <NUM> may be found within the per-shader preamble code block and may allow constants to be loaded from system memory <NUM> to on-chip constant memory on GPU <NUM>.

In some examples, the shader preamble may be executed by a scalar processor (e.g., a single arithmetic logic unit (ALU)) on shader core <NUM>. In other examples, the shader preamble may be executed by the parallel processing elements of shader core <NUM> (sometimes called a vector processor). Execution of the shader preamble may result in a constant value or set of values. The constant value preamble result may be stored in on-chip memory such as in uGPR <NUM>, constant memory <NUM> (e.g., constant RAM), GPU memory <NUM>, or system memory <NUM>. Constant memory <NUM> may include memory accessible by all elements of the shader core <NUM> rather than just a particular portion reserved for a particular warp or thread such as values held in uGPR <NUM> or GPR <NUM>. Constant memory <NUM> may also store data persistently between warps rather than needing to be reloaded with data prior to each warp. During execution of a subsequent warp of the execution of the shader the constant values (i.e. preamble results) calculated during the first warp of the execution of shader program <NUM>, <NUM>, or <NUM> may be retrieved from constant memory <NUM> rather than executing the redundant code. GPU <NUM> may ensure that only the first warp of the shader executes the shader preamble. GPU <NUM> may ensure that only the first warp of the shader executes the shader preamble via a flag in an on-chip internal state register, constant memory <NUM>, or GPU memory <NUM>. GPU <NUM> may also track that a warp that started execution of the shader preamble as the first warp. The flag denoting that a current warp is the first warp (or, in another example, that it is not the first warp) may be stored, by GPU <NUM>, as a value in an on-chip internal state register, constant memory <NUM>, or GPU memory <NUM>. GPU <NUM> may also track whether the first warp has completed execution of the shader preamble instructions. The flag denoting the first warp has (or, in another example, has not) completed execution of the shader preamble instructions may be stored, by GPU <NUM>, in an on-chip internal state register, constant memory <NUM> or GPU memory <NUM>. Shader core <NUM> can utilize these flags to determine whether to execute the shader preamble (e.g., if this is the first warp and/or the preamble has not been executed previously) or not (e.g., if this is not the first warp and/or the preamble has been executed previously). Shader core <NUM> may also delay execution of a second warp of threads of shader program <NUM>, <NUM>, or <NUM> until completion of the execution of the shader preamble and loading of the constant results of the preamble in constant memory <NUM>, GPU memory <NUM>, or uGPR <NUM> by the GPU <NUM>.

In an example, each type of shader core <NUM> can access context (e.g., flag) bits stored in an on-chip internal state register. Shader core <NUM> may have a <NUM>-bit preamble_token_taken context bit that may indicate that the present warp is/is not the first warp and/or a warp (or no warp) on shader core <NUM> has started to execute the preamble. Both of these bits may be initialized to false when a particular type of shader (e.g. shader core <NUM>) is loaded. For example, a first warp to execute a SHPS (e.g. a shader preamble start) instruction in a given shader core <NUM> or shader type finds the preamble_token_taken flag as false. Shader core <NUM> will set the preamble_token_taken flag to true. When the first warp executes a SHPE (e.g. shader preamble end) instruction, shader core <NUM> sets the preamble_completed flag to true. Shader core <NUM> will then continue executing code from the main shader instruction label. In a non-first warp, the preamble_token_taken flag may be set to true. All subsequent warps branch to the main code section (e.g., a MAIN label) and wait there until preamble_completed flag changes from false to true. When the change of the preamble_completed flag changes from false to true, shader core <NUM> executes subsequent waves.

<FIG> is a conceptual diagram showing a set of instructions <NUM> that include a shader preamble <NUM>. In this example, shader preamble <NUM> comprises a shader preamble start instruction (SHPS) instruction. The shader preamble start instruction will branch to the "Label_MAIN" label (e.g., in the main shader instructions <NUM>) if the preamble_token_taken flag is set to true only allow the shader preamble to be executed a single time. The instruction may also instruct the shader core <NUM> to set the preamble_token_taken flag to true when the preamble_token_taken flag is set to false.

The instruction (e.g., the ADD z, y, x instruction) illustrates a redundant instruction in the shader code. The instruction may be executed (e.g., "ADD z, y, x;" will add the values in "x" and "y" together and store the resulting value in "z"). Each of the redundant instructions is likewise executed. The redundant values may be saved to constant memory <NUM> via e.g., a store data into constant memory instruction (e.g., "STC c[<NUM>], z;" stores the value in "z" into constant RAM location <NUM>). The redundant values may also be moved to uGPR <NUM> or GPR <NUM>.

The next exemplary instruction may load a number of constants from a constant buffer into constant memory <NUM> via, e.g., a load constant instruction (e.g. "LDC c[<NUM>], index, CB <NUM>, <NUM>;" will load <NUM> constants from constant buffer (CB) <NUM> into constant RAM starting at location <NUM>. ) Shader preamble <NUM> closes with a shader preamble end instruction (SHPE). In certain implementations, there may only be a single shader preamble start and shader preamble end instruction in a shader program <NUM>, <NUM>, or <NUM>. Following shader preamble <NUM> is main shader instructions <NUM>.

The instructions in the shader preamble <NUM> includes instructions that produce the same results for all threads of the shader (e.g., because such instructions only operate on constant values) and do not change between warps of shader execution. These instructions may be identified by the compiler <NUM>.

Shader preamble <NUM> is then only executed a single time regardless of the number of warps of execution of the shader program <NUM>, <NUM>, or <NUM>. Main shader instructions <NUM> are executed separately for each warp. Results generated in the execution of shader preamble <NUM> are utilized in the execution of main shader instructions <NUM> and stored in constant memory <NUM>. At execution, shader core <NUM> utilizes a variety of flags to determine whether shader preamble <NUM> has executed and thus does not need to execute the preamble code of shader preamble <NUM> a second time as well as determining where the result(s) of the execution of the shader preamble <NUM> that are stored within constant memory <NUM>. The variety of flags includes a flag denoting that a current warp is the first warp (or, in another example, that it is not the first warp) and a flag denoting the first warp has (or, in another example, has not) completed execution of the shader preamble instructions. These flags may be stored, by GPU <NUM>, in in an on-chip internal state register, constant memory <NUM> or GPU memory <NUM>.

While the shader preamble <NUM> is illustrated as being in the beginning of shader code <NUM> prior to main shader instructions <NUM>, shader preamble <NUM> may be interspersed inside shader code <NUM> only being delimitated by the shader preamble start instruction (e.g. SHPS) and shader preamble end instruction (SHPE). Furthermore, a shader preamble may be inside a control flow. If a shader preamble is inside a control flow, the wave to execute the preamble may not be the first wave of the shader.

<FIG> is a conceptual diagram illustrating an example of data storage in a GPR of a shader core of a GPU. As illustrated, GPU <NUM> includes shader core <NUM>, and shader core <NUM> includes GPR <NUM>. As an example, shader core <NUM> may include thirty-two processing elements and each may execute one instance of a shader program to process one graphics item. GPR <NUM> may store data for the graphics items. For instance, GPR <NUM> may store attribute data for nine attributes for thirty-two graphics items. However, GPR <NUM> may store data for more or less than nine attributes for the thirty-two graphics items. Also, GPR <NUM> may store data that is not associated with an attribute of the graphics items, but is the data for a variable needed for processing the graphics items.

In the example illustrated in <FIG>, the graphics items are identified as P0-P31, which may be vertices. The attribute is identified by the variable following the graphics item identifier. For example, P0. X refers to the x-coordinate for the P0 graphics item, P0. Y refers to the y-coordinate for the P0 graphics item, and so forth. A refer to the red component, green component, blue component, and opacity of the P0 graphics item, respectively. The other graphics items (e.g., P1-P31) are similarly identified.

In other words, in <FIG>, vertices P0-P31 are each associated with a plurality of variables. As one example, each of vertices P0-P31 is associated with a variable that identifies the x-coordinate (P0. Each of vertices P0-P31 is associated with a variable that identifies the y-coordinate (P0. Y to P31Y), and so forth. Each one of these variables is needed for processing each of the plurality of graphics items. For instance, the variable that identifies the x-coordinate is needed for processing each of vertices P0-P31.

As also illustrated in <FIG>, each of the graphics items also includes a PRJ attribute. The PRJ attribute is a projection matrix that a vertex shader executing on processing elements of shader core <NUM> may utilize. In this example, the PRJ attribute is another variable that is needed for processing each of vertices P0-P31. For example, the vertex shader may multiply the projection matrix with the respective coordinates (e.g., multiply P0. PRJ with P0.

It should be understood that there may be various units in which GPU <NUM> may store data (e.g., values). GPU <NUM> may store data in system memory <NUM> or may store data in local memory (e.g., cache). GPR <NUM> of shader core <NUM> is distinct from both system memory <NUM> and the local memory of GPU <NUM>. For example, system memory <NUM> is accessible by various components of device <NUM>, and these components use system memory <NUM> to store data. The local memory of GPU <NUM> is accessible by various components of GPU <NUM>, and these components use the local memory of GPU <NUM> to store data. GPR <NUM>, however, may only be accessible by components of shader core <NUM>, and may only store data for the processing elements of shader core <NUM>.

In some examples, one or more variables of graphics items in a graphic warp are uniform across the graphic warp. In such examples, rather than storing the uniform data for the one or more variables in separate entries for each thread/fiber in GPR <NUM>, GPU <NUM> may store the uniform data a single time in uGPR <NUM> accessible by all threads/fibers in a warp/wave or in constant memory <NUM>.

In one example, uGPR <NUM> may include a plurality of storage locations, where each storage location is associated with one attribute of the plurality of attributes of the graphics items. For instance, as illustrated in <FIG>, each graphics item P0-P31 includes nine attributes (PRJ, x, y, z, w, R, G, B, and A). In this example, uGPR <NUM> may include nine storage locations, where the first location of uGPR <NUM> is associated with PRJ attribute, the second location of the uGPR <NUM> is associated with the x-coordinate, and so forth. Again, the data in uGPR <NUM> may be used by each thread of a warp.

Constants may be stored in constant buffers in system memory. Constant load instructions may be utilized to allow the compiler to load constants from system memory into constant memory <NUM>. Constants may also be stored in GPR <NUM> and uGPR <NUM> if constant memory <NUM> is full.

Traditionally, no data may be saved between warps. In some examples, GPRs <NUM> and uGPRs <NUM> are reloaded or recalculated for each wave. Constant memory <NUM> may be saved between warps. Shader core <NUM>, however, may access preamble instructions and execute them during the first warp. After the instructions have been executed, subsequent warps may access the result of these instructions in constant memory <NUM>.

<FIG> is a block diagram illustrating an example configuration of GPU <NUM> that may be used to implement the techniques for uniform predicates of this disclosure. GPU <NUM> is configured to execute instructions for a program in a parallel manner. GPU <NUM> includes a shader core <NUM> that includes a control unit <NUM>, processing elements 74A-74D (collectively "processing elements <NUM>"), instruction store <NUM>, GPR <NUM>, constant memory <NUM>, uGPRs <NUM>, state registers <NUM>, communication paths <NUM>, <NUM>, <NUM>, 86A-86D, and a load unit <NUM>. Communication paths 86A-86D may be referred to collectively as "communication paths <NUM>. " In some examples, GPU <NUM> may be configured as a single-instruction, multiple-data (SIMD) processing system that is configured to execute a plurality of threads of execution for a warp of a program (e.g., shader) using processing elements <NUM>. In such a SIMD system, processing elements <NUM> may together process a single instruction at a time with respect to different data items. The program may retire after all of the threads associated with the program complete execution.

Control unit <NUM> is communicatively coupled to instruction store <NUM> via communication path <NUM>, to processing elements <NUM> via communication path <NUM>, and to GPR <NUM> via communication path <NUM>. Control unit <NUM> may use communication path <NUM> to send read instructions to instruction store <NUM>. A read instruction may specify an instruction address in instruction store <NUM> from which an instruction should be retrieved. Control unit <NUM> may receive one or more program instructions from instruction store <NUM> in response to sending the read instruction. Control unit <NUM> may read shader preamble <NUM> and main shader instructions <NUM> from instruction store <NUM>. Control unit <NUM> determines whether the preamble has been previously executed (via a flag stored in on-chip state register <NUM>, uGPR <NUM>, or GPR <NUM>). Control unit determines whether the current warp is the first warp (via a flag stored in on-chip state register <NUM>, uGPR <NUM>, or GPR <NUM>). Control unit <NUM> may also change the foregoing flags when the underlying state changes (e.g., the preamble has been executed and/or the current warp is not the first warp). Use of the foregoing flags by control unit <NUM> ensures that the preamble code is only executed a single time and that no subsequent (e.g. second, third, etc.) warps may begin before the preamble has completed execution. Control unit <NUM> may use communication path <NUM> to provide instructions to processing elements <NUM>, and in some examples, to receive data from processing elements <NUM>, e.g., the result of a comparison instruction for evaluating a branch condition. In some examples, control unit <NUM> may use communication path <NUM> to retrieve data items values from state register <NUM>, uGPR <NUM>, GPR <NUM>, or constant memory <NUM>, e.g., to determine a branch condition. Although <FIG> illustrates GPU <NUM> as including a communication path <NUM>, in other examples, GPU <NUM> may not include a communication path <NUM>.

Constant values may originally be stored in constant buffers in system memory <NUM>. Load unit <NUM> may load, via instructions from control unit <NUM>, compiler <NUM>, and/or graphics driver <NUM>, the constant values from the constant buffers in system memory <NUM> to constant memory <NUM>, uGPR <NUM>, or GPR <NUM>. Load unit <NUM> may be configured to load constants in uGPR <NUM> if space allocated in constant memory <NUM> is full.

Each of processing elements <NUM> may be configured to process instructions for the program stored in instruction store <NUM>. In some examples, each of processing elements <NUM> may be configured to perform the same set of operations. For example, each of processing elements <NUM> may implement the same instruction set architecture (ISA). In additional examples, each of processing elements <NUM> may be an arithmetic logic unit (ALU). In further examples, GPU <NUM> may be configured as a vector processor, and each of processing elements <NUM> may be a processing element within the vector processor. In additional examples, GPU <NUM> may be a SIMD execution unit, and each of processing elements <NUM> may be a SIMD processing element within the SIMD execution unit.

The operations performed by processing elements <NUM> may include arithmetic operations, logic operations, comparison operations, etc. Arithmetic operations may include operations such as, e.g., an addition operation, a subtraction operation, a multiplication operation, etc. The arithmetic operations may also include, e.g., integer arithmetic operations and/or floating-point arithmetic operations. The logic operations may include operations, such as, e.g., a bit-wise AND operation, a bit-wise OR operation, a bit-wise XOR operation, etc. The comparison operations may include operations, such as, e.g., a greater than operation, a less than operation, an equal to zero operation, a not equal to zero operation, etc. The greater than and less than operations may determine whether a first data item is greater than or less than a second data item. The equal to zero and not equal to zero operations may determine whether a data item is equal to zero or not equal to zero. The operands used for the operations may be stored in registers contained in GPR <NUM> or uGPR <NUM>.

Each of processing elements <NUM> may be configured to perform an operation in response to receiving an instruction from control unit <NUM> via communication path <NUM>. In some examples, each of processing elements <NUM> may be configured to be activated and/or deactivated independently of the other processing elements <NUM>. In such examples, each of processing elements <NUM> may be configured to perform an operation in response to receiving an instruction from control unit <NUM> when the respective processing element 74A-74D is activated, and to not perform the operation in response to receiving the instruction from control unit <NUM> when the respective processing element 74A-74D is deactivated, i.e., not activated.

Each of processing elements 74A-74D may be communicatively coupled to GPR <NUM> via a respective communication path 86A-86D. Processing elements <NUM> may be configured to retrieve data from GPR <NUM>, uGPR <NUM>, and/or constant memory <NUM> and store data to GPR <NUM> via communication paths <NUM>, uGPR <NUM>, and/or constant memory <NUM>. The data retrieved from GPR <NUM>, uGPR <NUM>, and/or constant memory <NUM> may, in some examples, be operands for the operations performed by processing elements <NUM>. The data stored in GPR <NUM>, uGPR <NUM>, and/or constant memory <NUM> may, in some examples, be the result of an operation performed by processing elements <NUM>.

Instruction store <NUM> is configured to store a program for execution by GPU <NUM>. The program may be stored as a sequence of instructions. These instructions may include shader preamble <NUM> and main shader instructions <NUM>. In some examples, each instruction may be addressed by a unique instruction address value. In such examples, instruction address values for later instructions in the sequence of instructions are greater than instruction address values for earlier instructions in the sequence of instructions. The program instructions, in some examples, may be machine-level instructions. That is, in such examples, the instructions may be in a format that corresponds to the ISA of GPU <NUM>. Instruction store <NUM> is configured to receive a read instruction from control unit <NUM> via communication path <NUM>. The read instruction may specify an instruction address from which an instruction should be retrieved. In response to receiving the read instruction, instruction store <NUM> may provide an instruction corresponding to the instruction address specified in the read instruction to control unit <NUM> via communication path <NUM>.

Instruction store <NUM> may be any type of memory, cache or combination thereof. When instruction store <NUM> is a cache, instruction store <NUM> may cache a program that is stored in a program memory external to GPU <NUM>. Although instruction store <NUM> is illustrated as being within GPU <NUM>, in other examples, instruction store <NUM> may be external to GPU <NUM>.

GPR <NUM> is configured to store data items used by processing elements <NUM>. In some examples, GPR <NUM> may comprise a plurality of registers, each register being configured to store a respective data item within a plurality of data items operated on GPU <NUM>. GPR <NUM> may be coupled to one or more communication paths (not shown) that are configured to transfer data between the registers in GPR <NUM> and a memory or cache (not shown).

uGPR <NUM> is configured to store data items used by processing elements <NUM> and each memory element within uGPR <NUM> is configured to be accessible by multiple processing elements (e.g. threads/fibers) of a wave/warp.

State register <NUM>, uGPR <NUM>, or GPR <NUM> may store a number of flags used by control unit <NUM>. Flags stored in State register <NUM>, uGPR <NUM>, or GPR <NUM> may include a flag to denote that the preamble has been previously executed. This flag may allow control unit <NUM> to time the processing of the threads in the warp to begin after the shader preamble <NUM> has completely executed and the results of the execution are stored in constant memory <NUM>, uGPR <NUM>, and/or GPR <NUM>. The flag denoting that the preamble has been previously executed may initially be set to "off" in State register <NUM>, uGPR <NUM>, or GPR <NUM>. State register <NUM>, uGPR <NUM>, or GPR <NUM> may also include a flag to denote that the current warp is the first warp. The flag denoting that the current warp is the first warp may initially be set to "on.

Although <FIG> illustrates a single GPR <NUM> for storing data used by processing elements <NUM>, in other examples, GPU <NUM> may include separate, dedicated data stores for each of processing elements <NUM>. GPU <NUM> illustrates four processing elements <NUM> for exemplary purposes. In other examples, GPU <NUM> may have many more processing elements in the same or a different configuration.

Control unit <NUM> is configured to control GPU <NUM> to execute instructions for a program stored in instruction store <NUM>. For each instruction or set of instructions of the program, control unit <NUM> may retrieve the instruction from instruction store <NUM> via communication path <NUM>, and process the instruction. In some examples, control unit <NUM> may process the instruction by causing an operation associated with the instruction to execute on one or more of processing elements <NUM>. For example, the instruction retrieved by control unit <NUM> may be an arithmetic instruction that instructs GPU <NUM> to perform an arithmetic operation with respect to data items specified by the instruction, and control unit <NUM> may cause one or more of processing elements <NUM> to perform the arithmetic operation on the specified data items. In further examples, control unit <NUM> may process the instruction without causing an operation to be performed on processing elements <NUM>.

Control unit <NUM> may cause an operation to be performed on one or more of processing elements <NUM> by providing an instruction to processing elements <NUM> via communication path <NUM>. The instruction may specify the operation to be performed by processing elements <NUM>. The instruction provided to the one or more of processing elements <NUM> may be the same as or different than the instruction retrieved from instruction store <NUM>. In some examples, control unit <NUM> may cause the operation to be performed on a particular subset of processing elements <NUM> (including by a single processing element) by one or both of activating a particular subset of processing elements <NUM> upon which the operation should be performed and deactivating another subset of processing elements <NUM> upon which the operation should not be performed. Control unit <NUM> may activate and/or deactivate processing elements <NUM> by providing respective activation and/or deactivation signals to each of processing elements <NUM> via communication path <NUM>. In some examples, control unit <NUM> may activate and/or deactivate processing elements <NUM> by providing activation and/or deactivation signals to processing elements <NUM> in conjunction with providing an instruction to processing elements <NUM>. In further examples, control unit <NUM> may activate and/or deactivate processing elements <NUM> prior to providing an instruction to processing elements <NUM>. Control unit <NUM> may execute a plurality of threads of execution for a program using processing elements <NUM>. A plurality of threads to be executed in parallel is sometimes called a warp. Each of processing elements <NUM> may be configured to process instructions of the program for a respective thread of the plurality of threads. For example, control unit <NUM> may assign each thread of execution to an individual one of processing elements <NUM> for processing. The threads of execution for the program may execute the same set of instructions with respect to different data items in a set of data items. For example, processing element 74A may execute a first thread of execution for a program stored in instruction store <NUM> with respect to a first subset of data items in a plurality of data items, and processing element 74B may execute a second thread of execution for the program stored in instruction store <NUM> with respect to a second subset of data items in the plurality of data items. The first thread of execution may include the same instructions as the second thread of execution, but the first subset of data items may be different than the second subset of data items. Processing elements <NUM> may execute main shader instructions <NUM>. Processing elements <NUM> may execute shader preamble <NUM>. In another example, shader core <NUM> may utilize a separate scalar processing unit <NUM>, via communications path <NUM>, to execute the instructions of shader preamble <NUM>.

Scalar processing unit <NUM> may be any type of processor that is configured to operate on one data item at a time. Like processing elements <NUM>, scalar processing unit <NUM> may include an ALU. The operations performed by scalar processing unit <NUM> may include arithmetic operations, logic operations, comparison operations, etc. Arithmetic operations may include operations such as, e.g., an addition operation, a subtraction operation, a multiplication operation, a division operation, etc. The arithmetic operations may also include, e.g., integer arithmetic operations and/or floating-point arithmetic operations. The logic operations may include operations, such as, e.g., a bit-wise AND operation, a bit-wise OR operation, a bit-wise XOR operation, etc. The comparison operations may include operations, such as, e.g., a greater than operation, a less than operation, an equal to zero operation, a not equal to zero operation, etc. The greater than and less than operations may determine whether a first data item is greater than or less than a second data item. The equal to zero and not equal to zero operations may determine whether a data item is equal to zero or not equal to zero. The operands used for the operations may be stored in registers contained in GPR <NUM>.

When a shader instruction referencing a result of a preamble instruction is executed, the (constant) result is retrieved from GPR <NUM> instead of executing the shader preamble instructions again.

<FIG> is a flowchart illustrating an example method according to the techniques of this disclosure. The techniques of <FIG> may be implemented by one or more of GPU <NUM> and/or processor <NUM> (see <FIG> and <FIG>).

GPU <NUM> is configured to receive from a shader compiler <NUM> a shader program comprising a preamble code block and a main shader code block (<NUM>). The preamble code block being executable to produce one or more results, the one or more results are the same one or more results for each of a plurality of groups of threads (e.g., a wave/warp) executing the shader program. GPU <NUM> is further configured to execute the preamble code block to produce one or more results (<NUM>). The preamble code block may be executed by scalar processing unit <NUM> on GPU <NUM>. The preamble code block may evaluate to a constant value.

GPU <NUM> is further configured to store the one or more results of the preamble code block (<NUM>). The results may be stored in on-chip random access memory (RAM). The on-chip RAM may be accessible by each of the plurality of groups of threads and may be accessible by all processing elements of a shader core <NUM>. The on-chip RAM may be accessible by GPU <NUM> without accessing a main bus. The on-chip RAM may include a writeable buffer managed cache. Upon a determination that the GPU <NUM> has completed storing the result of the code block of instructions common to the plurality of groups of threads of the shader, GPU <NUM> is configured to execute the main shader code block for each thread of a group of threads of the plurality of groups of threads using the one or more results produced by executing the preamble code block (<NUM>). In one example of the disclosure, GPU <NUM> may be configured to identify the preamble code block based on identifying a shader preamble start instruction.

In a further example of the disclosure, GPU <NUM> may be configured to track whether or not that the preamble code block has been executed by the first group of threads allowing the shader to execute a subsequent group of threads of the plurality of groups of threads. GPU <NUM> may also be configured to track whether or not any group of threads of the plurality of groups of threads has executed prior to the first group of threads to determine, at least in part, whether or not the preamble code block has been executed previously. GPU <NUM> may also be configured to track whether or not the preamble code block has been executed to determine, at least in part, whether to execute the preamble code block. In an additional example of the disclosure, GPU <NUM> may be configured to load the one or more results of the preamble code block from constant buffers located in system RAM (e.g., not on-chip RAM) into on-chip constant memory.

A shader compiler (e.g. compiler <NUM>) running on processor <NUM> may identify a code block of instructions being executable to produce the one or more results being the same one or more results for each of a plurality of groups of threads executing the shader program. The shader compiler (e.g. compiler <NUM>) running on processor <NUM> may also group the code block of instructions into the preamble code block of the shader program. Such grouping may be used by GPU <NUM>. Identification of the code block of instructions common to the plurality of groups of threads of the shader instructions may include identification of instructions that evaluate to a constant. The identifiable code block may be organized into a preamble code. The preamble code may be configured to be executed by a first group of threads of a plurality of groups of threads. The one or more result of the executed preamble code may be useable by other groups of the plurality of groups of threads.

Compiler <NUM> executing on processor <NUM> may receive shader code (<NUM>). Compiler <NUM> executing on processor <NUM> may identify instructions that evaluate to a constant (<NUM>). Compiler <NUM> executing on processor <NUM> may group the instructions into a shader preamble (<NUM>). The shader preamble may be delineated by a shader preamble start and a shader preamble end command. Compiler <NUM> executing on processor <NUM> may convert instructions in the shader code into object code (<NUM>). Such object code is configured to run on GPU <NUM>. Compiler <NUM> executing on processor <NUM> may send the object code to GPU <NUM> for execution on a shader core <NUM>.

If implemented in software, the functions may be stored on or transmitted over, as one or more instructions or code, a computer-readable medium and executed by a hardware-based processing unit. Computer-readable media may include computer-readable storage media, which corresponds to a tangible medium such as data storage media. In this manner, computer-readable media generally may correspond to tangible computer-readable storage media which is non-transitory.

It should be understood that computer-readable storage media and data storage media do not include carrier waves, signals, or other transient media, but are instead directed to non-transient, tangible storage media.

Claim 1:
A method of operating a graphic processing unit,GPU (<NUM>), comprising:
receiving (<NUM>), by the GPU (<NUM>) from a shader compiler (<NUM>), a shader program comprising a preamble code block and a main shader code block, the preamble code block comprising threads which produce one or more results that are the same each time the threads are executed during execution of the shader program;
executing, by the GPU (<NUM>), using a plurality of warps of execution of the shader program, multiple instances of the shader program, wherein executing each of the multiple instances of the shader program comprises:
for a first warp, determining whether or not a first flag indicates that the execution of the preamble code block has started in any other warp;
responsive to the first flag indicating that execution of the preamble code block has not started, setting the first flag to indicate that execution of the preamble code block has started; executing (<NUM>) the preamble code block to produce the one or more results;
and storing (<NUM>) the one or more results of the preamble code block;
responsive to the first flag indicating that execution of the preamble code block has started, not executing the preamble code block;
for each warp, determining whether or not a second flag indicates that execution of the preamble code block is complete;
responsive to the second flag indicating that execution of the preamble code block is not complete, waiting for the second flag to indicate that execution of the preamble code block is complete; and
responsive to the second flag indicating that execution of the preamble code block is complete, executing (<NUM>), the main shader code block using the one or more results produced by executing the preamble code block.