The present disclosure relates generally to compilers and, more particularly, to methods, apparatus, and articles of manufacture to iteratively compile software to meet user-defined criteria.
Software compilers have several optimization capabilities. Some compiler capabilities include user selectable compiler options that enable the compiler to optimize object code with respect to different, sometimes competing, performance criteria. For example, some compiler options are associated with optimizing object code for increased execution speed (i.e., decreased execution time). In this case, the compiler may compile source code so that execution speed is regarded as the most important parameter to optimize and code size is regarded as a less important characteristic of the resulting object code.
Typically, compiler options are selected by a user (e.g., a programmer) by setting switches or flags in a compiler application prior to compiling the source code. The compiler then compiles the source code while attempting to generate object code that meets the criteria specified in the selected compiler options. If a user is not satisfied with the performance of the resulting object code, the user may select different compiler options or configure the compiler to focus on optimizing particular code modules or areas in the source code. This process of selecting and reselecting the compiler options can be an iterative process that is repeated until the user is satisfied with the level of optimization of the object code. To be effective, this process typically requires a skilled person or programmer that is intimately familiar with the capabilities of the compiler and compiler options so that the person can select or change the compiler options to achieve the desired optimization results.
Some recently developed compilers attempt to improve the above-noted compiler option selection process by compiling source code based on desired performance criteria specified by a user via a user interface. For example, a user may specify that the compiler should reduce the binary code size of object code by a particular percentage. The user may alternatively or additionally specify that the compiler should increase the execution speed of the object code by a particular percentage. Although this simplifies a user's burden of selecting compiler options, traditional compilers lack a feedback mechanism for users to make informed optimization decisions. In addition, these compilers lack the capability to inform users how certain optimizations will affect other performance aspects of object code. Further, traditional compilers require that users manually adjust optimization options and performance criteria following each compilation until the compiler generates object code having acceptable performance.
An example compiler 100 constructed in accordance with the teachings of the invention is shown in
The example compiler 100 illustrated herein is structured to use an automated compiler options selection process to generate object code having performance characteristics that meet or exceed target performance characteristics specified by a user. The performance characteristics may be related to the compilation process (e.g., compilation duration) or the performance of the object code (e.g., binary size, execution time, stack size, heap size, etc.). Target performance characteristics may be specified, for example, according to system requirements or software development project requirements. System requirements may include, for example, memory capacity of a device (e.g., a personal digital assistant (PDA), a mobile phone, an embedded system, etc.), processing power, battery capacity, etc. Project requirements may include, for example, the time available to compile or build a project.
Particular system architectures of consumer devices (e.g., mobile phones, PDA's, etc.) may set forth various limitations on software. For example, to increase battery life of a portable device or to keep system costs low, a system architecture may have a limited amount of memory, which may constrain some software to a minimal amount of memory usage (e.g., a limited stack size). In this case, a programmer may specify a target performance memory characteristic based on the amount of memory available in the system architecture. The example compiler 100 illustrated herein may be configured to repeatedly compile the source code until it generates object code having a code size that is substantially equal to or less than the available amount of memory. Each time that the resulting object code is unacceptable or not substantially less than or equal to the specified amount of memory, the compiler 100 may automatically select new compiler options to further decrease the code size and recompile the source code based on the new compiler options. In this manner, the illustrated compiler 100 may recompile the source code a plurality of times based on a corresponding plurality of compiler options configurations to generate a plurality of object code until one of the plurality of object code has acceptable performance characteristics, or until a timeout event (e.g., completion of a predetermined number of recompilations) occurs.
Often software development projects have time constraints that define the amount of time available to build or compile the project. For example, some software development projects employ a daily build and test process. Development groups sometimes build and test their project overnight, which limits the amount of time available for compiling the project. In this case, a programmer may specify a target compilation time/duration performance characteristic so that the example compiler 100 illustrated in
The example compiler 100 of described herein may obtain source code and user-defined performance characteristic values or target performance characteristic values from a user. The compiler 100 may compile the source code to generate object code and then profile the object code to determine measured performance characteristic values associated with the object code. The compiler 100 may then compare the measured performance characteristic values to the target performance characteristic values. If the measured performance characteristic values are unacceptable or not substantially similar to, equal to, or better than the target performance characteristic values, the compiler 100 may select one of a plurality of compiler options configurations based on empirical data correlating the compiler options configurations to the performance characteristics and structural characteristics of the source code and/or the object code. The compiler 100 may then recompile the source code based on the selected compiler options configuration to generate new object code. In this manner, the compiler 100 may iteratively compile the source code, compare measured and target performance characteristic values, and select a subsequent compiler options configuration for each subsequent compilation without obtaining further user input until the measured characteristic values substantially meet or exceed the target performance characteristic values, until the compiler has compiled the source code a particular number of times, or until the compiler has exhausted all compiler options configurations.
The target performance characteristics may be absolute performance characteristic values (e.g., an absolute code size, an absolute execution time, an absolute compilation time, etc.) or relative performance characteristic values that are based on the performance characteristics of a baseline object code. The compiler 100 may generate baseline object code by compiling source code using a baseline compiler options configuration. The user may then specify relative performance characteristic values in terms of a percentage of baseline performance characteristics associated with the baseline object code.
If the compiler 100 does not generate object code having acceptable performance characteristics after the compiler has recompiled the source code a predetermined number of times or after the compiler has exhausted all possible compiler options configurations, the compiler generates one or more tables showing the performance results associated with each object code that was generated based on each of the selected compiler options configurations. For example, the tables may include the example compiler options performance comparison table and/or the example compiler options configurations ranking table described below in connection with
A user may use the comparison and ranking information provided in the tables to make decisions regarding performance trade-offs or different threshold values that will enable the compiler 100 to generate object code having acceptable performance characteristics (e.g., measured performance characteristics that are relatively similar to the target performance values or within threshold limits of the target performance values). For example, a user may analyze the comparison and/or ranking tables of
The example compiler 100 shown in
For the purpose of obtaining source code, the example apparatus 100 is provided with a source code interface 102. In the illustrated example, the source code interface 102 is configured to obtain source code 103 from a memory (e.g., the system memory 924 or mass storage memory 925 of
For the purpose of characterizing source code, the example apparatus 100 is provided with the source code profiler 104. In the illustrated example, the source code profiler 104 is configured to characterize the source code 103 obtained from the source code interface 102 to generate a source code profile for the source code 103. For example, the source code profiler 104 may analyze the source code 103 and determine the types of structural characteristics associated with the source code 103. Structural characteristics may include the number of functions in the source code 103, the number of function calls, the types of function calls (e.g., call by reference, call by value, etc.), types of variables initialized (e.g., global variables, local variables, volatile variables, etc.), types of pointers, number of pointers, type castings, re-entrant/non-reentrant functions, number of and types of data structures, etc. After characterizing the source code 103, the source code profiler 104 communicates the source code profile to a database repository 110 (described below). The source code profiler 104 also communicates the source code 103 to a compiler engine 106 (described below) and communicates an interrupt or message to a compiler options selector 120 (described below) informing the compiler selector 120 that new source code has been obtained and is ready to be compiled.
In the illustrated example, the compiler engine 106 is configured to generate object code 107 by compiling the source code 103 based on compiler options configurations obtained from the compiler options selector 120. The compiler engine 106 is configured to compile a particular source code one or more times until the resulting object code and/or the compilation process have characteristics that are substantially similar to, equal to, or better than target performance characteristics. The compiler engine 106 may first compile the source code 103 based on an initial compiler options configuration and subsequently recompile the source code 103 based on one or more other compiler options configuration(s) selected by the compiler options selector 120.
The compiler engine 106 is configured to optimize the object code 107 and/or the compiling process based on the provided compiler options configurations. For example, if the compiler options configuration has a loop unrolling optimization option, the compiler engine 106 may unroll loop functions in the source code during the compiling process. Additionally, the time spent during the compiling process (i.e., the compilation time) may be controlled based on the types of optimization options provided to the compiler engine 106. For example, if a target compilation time is relatively short and the source code profile for the source code 103 indicates a large number of loop functions, a compiler options configuration may not include a loop unrolling optimization option, thus causing the compiler engine 106 to reduce the compilation time by not having to optimize a large quantity of loops.
For the purpose of characterizing object code, the example apparatus 100 is provided with the object code profiler 108. In the illustrated example, the object code profiler 108 is configured to generate object code profiles for the object code 107 obtained from the compiler engine 106 by determining structural characteristics and measured performance characteristics of the object code 107. For example, the object code profiler 108 may determine binary sizes and instruction-related characteristics of the object code 107. Instruction-related characteristics may include the types of and number of instructions in the object code 107 such as, for example, the number of jumps, conditional branches, write operations, read operations, etc.
The object code profiler 108 may also determine execution-related characteristics. For instance, in the illustrated example, the object code profiler 108 includes an execution engine configured to execute the object code 107 while the object code profiler 108 measures the execution speed and other execution-related performance characteristics of the object code 107. Example execution-related characteristics include execution time (e.g., the time required for a complete run of the object code), dynamic code size (e.g., the size of the working set associated with the object code, number of pages of virtual memory needed to store the working set, etc.), power consumption (e.g., the power consumption of the processor to run the object code), thread usage (e.g., the number of parallel threads that are used to execute the object code), architectural system criteria (e.g., number of registers used during execution), micro-architectural events (e.g., cache hits/misses, branches taken, etc.), etc. Of course, these are merely some examples of execution-related characteristics. The object code profiler 108 may be configured to measure any other execution-related characteristics.
Further, the object code profiler 108 may be configured to measure performance characteristics associated with the compilation process. For example, the object code profiler 108 may measure or determine a compilation time characteristic corresponding to the amount of time required by the compiler engine 106 to generate the object code 107. For example, the compiler engine 106 may issue interrupts or messages to the object code profiler 108 informing the object code profiler 108 when the compiler engine 106 starts and ends a compiling process. Alternatively or additionally, the compiler engine 106 may generate a start compile timestamp and an end compile timestamp, or a total compile time value in a header of the object code 107. In either case, the object code profiler 108 may use compile time information to add a compiling time value to the object code profile of the object code 107. The object code profiler 108 stores the measured performance characteristics and structural characteristics in the object code profile for the object code 107. The object code profile is stored in the database repository 110.
For the purpose of storing source and object code profiles, compiler options, historical compilation data and other compiler-related information, the example apparatus 100 is provided with the database repository 110. The database repository 110 may comprise one or more databases or data structures and may be implemented using a memory such as, for example, the mass storage memory 925 (
The empirical corollary database 111e may include a plurality of compiler options, source and object code structural characteristics, and measured performance characteristic values. The information in the empirical corollary database 111e may be collected over time from various compilation processes and may include ranking information associated with compiler options, compiler options configurations, and performance characteristics associated therewith. The empirical corollary database 111e may be used by the example apparatus 100 to select compiler options configurations by comparing the structural characteristics of source code (e.g., the source code 103) generated by the source code profiler 104 and object code (e.g., the object code 107) generated by the object code profiler 108 to structural characteristics stored in the empirical corollary database 111e to determine a compiler options configuration that can be used to generate object code having performance characteristics that meet or exceed the target performance characteristics.
Further, the database repository 110 may be used to store project configuration databases or files. Project configuration databases may be used for long-term software development projects and may be used to store compiler options configurations that may be used by the compiler engine 106 to compile object code within compiler-process-related performance characteristics (e.g., compilation time). In this manner, during a software development project, when a development team builds a project, the example apparatus 100 can ensure that the compilation process is performed according to the compilation process performance characteristics specified by the development teams. As the development team changes source code files or modules during the development cycle, the example apparatus 100 may update the project configuration database when necessary by selecting new compiler options configurations to ensure that project builds meet specified target performance characteristics for the compilation process.
For the purpose of obtaining user input or feedback, the example apparatus 100 is provided with an input interface 112. In the illustrated example, the input interface 112 is used to enter target performance characteristics, select a compiler options configuration, and provide the example apparatus 100 with other compiler-related input. Target performance characteristics entered via the input interface 112 may be communicated to, and stored in, the database repository 110 in, for example, a target performance characteristics database. A compiler options configuration selected via the input interface 112 may be communicated to the compiler options selector 120. The input interface 112 may be implemented using a keyboard, a touchscreen, and/or any other suitable user input device(s).
In order to analyze performance of the compilation process and the resulting object code, the example apparatus 100 is provided with a performance analyzer 114. For example, the performance analyzer 114 obtains measured performance characteristics of the object code 107 (e.g., code size, execution time, etc.) and the compilation process (e.g., compilation time) and target performance characteristic values from the database repository 110, and determines whether measured performance characteristic values are substantially similar to, equal to, or better than the target performance characteristic values by comparing the measured performance characteristic values to the target performance characteristic values. If the performance analyzer 114 determines that the object code 107 has performance characteristics (e.g., the measured performance characteristics) that satisfy the target performance characteristics, then the performance analyzer 114 may output via an output interface 118 described below, the compiler options configuration that the compiler engine 106 used to generate the object code having acceptable performance characteristics. If the performance analyzer 114 determines that a most recent object code does not have performance characteristics that satisfy the target performance characteristics, the performance analyzer 114 may store a message or flag in the database repository 110 indicating that the last compilation process did not produce acceptable object code.
In the illustrated example, the performance analyzer 114 also generates percentage improvements or differences based on the measured and/or target performance characteristics as described below in connection with
For the purpose of generating tables, the example apparatus 100 may be provided with the table generator 116. The table generator 116 of the illustrated example is configured to generate tables associated with object code performance and compilation process performance based on target performance characteristic values and measured performance characteristic values. For example, the table generator 116 may generate compiler options performance comparison tables (e.g., the example compiler options performance comparison table 200 of
In the illustrated example, the table generator 116 is also configured to store the tables in the database repository 110 in one or more table databases. The table generator 116 may be configured to communicate the tables to the output interface 118 (directly or via the database repository 110) to enable the output interface 118 to display the tables to a user. The table generator 116 may communicate the compiler options configurations used to generate each table to the compiler options selector 120. In this manner, when a user selects a compiler options configuration via the input interface 112, the compiler options selector 120 may communicate the selected configuration to the compiler engine 106.
To output compiler-related information to a user, the example apparatus 100 is provided with the output interface 118. In the illustrated example, the output interface 118 is configured to display to a user compiler options related tables obtained from the table generator 116. The output interface 118 may be implemented using a computer display such as, for example, a cathode ray tube (CRT), a liquid crystal display (LCD), a plasma display, etc. Alternatively, or additionally, the output interface 118 may be implemented using a printer configured to print the tables obtained from the table generator 116 or any other information of interest to a programmer.
In order to automatically select compiler options and generate compiler options configurations, the example apparatus 100 is provided with the compiler options selector 120. In the illustrated example, the compiler options selector 120 is configured to obtain compiler options from the table generator 116 and/or the database repository 110 and to obtain from the performance analyzer 114 performance analyses results such as, for example, performance differences or improvements described below in connection with
The compiler options selector 120 may select and/or generate compiler options configurations in response to interrupts, messages, or other communications from other portions of the example apparatus 100. For example, after the source code profiler 104 characterizes new source code, the source code profiler 104 is configured to communicate an interrupt to the compiler options selector 120. The compiler options selector 120 is configured to respond by communicating an initial compiler options configuration to the compiler engine 106. The initial compiler options configuration may be a general or baseline set of options that is, for example, relatively conservative, and typically used for the initial compilation of newly obtained source code. The baseline compiler options configuration causes the compiler engine 106 to generate object code having a baseline optimization (which may be substantially non-optimized). The example apparatus 100 may analyze the generated object code (via the object code profiler 108, the comparison table generator 112, the performance analyzer 114, and the compiler options selector 120) to gauge or empirically determine the effects that the structural characteristics of the source code 103 have on the compilation process and resulting object code. The compiler options selector 120 may select subsequent compiler options configurations to optimize the object code 107 or the compilation process based on the object code analysis and target performance characteristics.
The compiler options selector 120 is also configured to obtain compiler options and/or compiler options-related input from the input interface 112 (e.g., directly or via the database repository 110). In this manner, if a user selects a compiler options configuration via the input interface 112, the compiler options selector 120 may obtain the compiler options configuration from the table generator 116 or the database repository 110 and communicate the configuration to the compiler engine 106. The compiler options selector 120 is also configured to select compiler options from the database repository 110 based on user feedback such as, for example, performance trade-offs or updated target performance characteristic values.
The table generator 116 (
The comparison table 200 may also enable a user to change one or more of the target performance characteristic values to trade off performance of one characteristic (e.g., execution speed) for a better performance of another characteristic (e.g., code size). The user may provide input to the example apparatus 100 via the input interface 112 and configure the example apparatus 100 to perform a subsequent set of compiling processes based on a selected compiler options configuration or to determine another set of compiler options configurations to achieve updated target performance characteristic values and generate a subsequent compiler options comparison table if the updated target performance characteristic values are not achieved after performing a predetermined number of compilations.
Turning in detail to
The target performance characteristic values provided in the target performance row 206 may be absolute performance characteristic values or relative performance characteristic values. Absolute performance characteristic values define actual measured performance characteristics. For example, an absolute memory constraint may be specified in terms of the desired object code binary size. In this case, the binary size of object code should be substantially equal to or less than the specified absolute memory constraint. A relative performance characteristic value is based on measured performance characteristic values of a baseline object code. For example, the compiler engine 106 may generate baseline object code (e.g., the object code 107 of
As shown above in Equation 1, a relative performance characteristic (R) specified as a percentage may be expressed in terms of a baseline performance characteristic value (B) and a target performance characteristic value (T). More specifically, in Equation 1, the target performance characteristic value T is subtracted from the baseline performance characteristic value B to generate a difference value (B−T). The difference value (B−T) is divided by the target performance characteristic value T to generate a quotient value
that is then multiplied by one hundred to determine the relative performance characteristic R.
As shown above in Equation 2, the performance analyzer 114 (
add the quotient value to one to generate a sum value
and multiply the sum value
by the baseline performance characteristic value B.
The performance evaluation values provided in the plurality of columns 202 for each performance characteristic may be determined according to the percentage function shown in Equation 3 below or the error function shown in Equation 4 below.
As shown in Equation 3 above, the percentage function may be used to determine a percentage difference value P between a measured performance characteristic value (M) and the target performance characteristic value T. In particular, the performance analyzer 114 described above in connection with
and multiplying the quotient value
by 100.
As shown in
The performance analyzer 114 may determine a ratio according to Equation 5 above by dividing a performance improvement of a first measured performance characteristic value ΔC1 by a second measured characteristic value C2. The performance improvement of the first performance characteristic value ΔC1 is determined by subtracting a measured performance characteristic value MC1 from a baseline performance characteristic value BC1.
The baseline performance characteristic value is associated with a baseline object code compiled by the compiler based on a baseline compiler options configuration. Each of the compiler options configurations ranked in the ranking table 300 are ranked based on an improvement or performance difference between the object code of the corresponding compiler options configurations and the baseline object code. In this manner, if the first performance characteristic C1 is execution speed and the second performance characteristic C2 is code size, when two different compilations produce first and second object code having the same executions speed improvement ΔC1, the object code having the smaller code size C2 gets a higher rank. Further, when two optimizations resulting in first and second object code having the same code size C2, the object code having a higher performance improvement ΔC1 is ranked higher.
Flowcharts representative of example machine readable instructions for implementing the example apparatus 100 of
The program begins at
The source code profiler 104 (
The compiler engine 106 then compiles the source code 103 to generate object code (e.g., the object code 107 of
The performance analyzer 114 (
If the example apparatus 100 determines that the measured performance characteristic values are not acceptable (i.e., do not satisfy the target performance characteristic values), then the example apparatus 100 determines whether it should recompile to generate different object code (e.g., perform another compilation of the source code 103) (block 416). For example, the example apparatus 100 may determine if it has exhausted all possible compiler options configurations or if it has generated a sufficient number of object code results (e.g., has performed a predetermined number of compilations). In particular, a user may configure the example apparatus 100 to generate a predetermined number of object code results before providing performance analysis results to a user. In this case, if the example apparatus 100 generates the predetermined number of object code results before generating object code having acceptable performance characteristics (block 416), then control advances to block 420 and the example apparatus 100 does not perform further compilations of the source code 103.
If, on the other hand, the example apparatus 100 determines that it should generate another object code 107 (block 416), then the compiler options selector 120 selects a next compiler options configuration (block 418) and control is passed back to block 410. The compiler options selector 120 determines a next compiler options configuration based on measured performance characteristics of the object code 107, target performance characteristics, source and object code structural characteristics, and empirical data correlating the compiler options configurations to the performance characteristics and the structural characteristics of the source code and object code. The operation of block 418 may be implemented as described below in connection with the flowchart of
If the example apparatus 100 determines at block 414 that the measured performance characteristics of the object code 107 are acceptable (i.e., satisfy the target performance characteristics), or if the example apparatus 100 determines at block 416 that it should not generate another object code result, the performance analyzer 114 and the table generator 116 rank the compiler options configurations and store the rankings in the database repository 110 (block 420). For example, the performance analyzer 114 and the table generator 116 of
The performance analyzer 114 and the table generator 116 then generate a compiler options configurations comparison table (e.g., the compiler options performance comparison table 200 of
The output interface 118 (
After a user analyzes the displayed results, the user may provide feedback or user input via the input interface 112 (
The example apparatus 100 then generates and/or updates information in the database repository 110 (
After the example apparatus 100 generates or updates database information, the example apparatus 100 determines whether to recompile the source code 103 based on the user-defined input (block 430). For example, if the example apparatus 100 outputs a message at block 424 indicating that an acceptable object code was generated, the example apparatus 100 may obtain that object code from, for example, the database repository 110 or any other memory space and provide it to the user. If the user-defined input obtained at block 426 includes updated target performance characteristic values, the example apparatus 100 may repeat the compilation process (e.g., return control to block 408 of
An execution engine in the object code profiler 108 then executes the object code 107 (block 504). During or after execution of the object code 107, the object code profiler 108 determines run-time performance characteristics of the object code 107 (block 506). For example, the object code profiler 108 may measure execution time of one or more functions or sections of the object code 107. The object code profiler 108 may also determine system resource related performance characteristics such as, for example, required stack size, required registers, cache usage, etc.
The object profiler 108 then stores the structural characteristics and run-time performance characteristics of the object code 107 in the database repository 110 (
The compiler options selector 120 then selects a compiler options configuration (block 606). In the illustrated example, the compiler options selector 120 selects a compiler options configuration based on empirical data stored in the empirical corollary database 111e (
Alternatively, the compiler options selector 120 may select a compiler options configuration from the project configurations database 111d (
The performance analyzer 114 then obtains a baseline performance characteristic value (block 704). As described above in connection with Equation 5, the compiler options configurations are ranked based on an improvement or performance difference between a measured characteristic for baseline object code and the measured characteristic for subsequently compiled object code. For example, if the user specifies that the compiler options configurations should be ranked based on improvements or performance differences in execution time, then the performance analyzer 114 obtains from the database repository 110 a baseline execution time characteristic value associated with baseline object code.
The performance analyzer 114 then generates a first ratio based on the first set of measured performance characteristic values (block 706). For example, the performance analyzer 114 may generate the first ratio based on the first execution time characteristic value and the first object code size characteristic value obtained at block 702 and the baseline execution time characteristic value obtained at block 704 as described above in connection with Equation 5 and
The table generator 116 (
The performance analyzer 114 then obtains performance differences between the target performance characteristic values and the measured performance characteristic values (block 804). For example, the performance analyzer 114 may determine percentage differences or percentage errors based on the target and measured characteristic values obtained at block 802 as described above in connection with Equations 3 and 4.
The table generator 116 then obtains the compiler options configurations associated with the performance differences generated at block 804 from the database repository 110 (block 806). The table generator 116 then generates a comparison table based on the compiler options configurations obtained at block 806 and corresponding performance differences generated at block 804 (block 808). More specifically, the table generator 116 stores the compiler options configurations and corresponding performance differences in the example compiler options performance comparison table 200 as described above in connection with
The table generator 116 then stores the comparison table generated at block 808 in the database repository 110 (block 810). Control is then returned or passed to a calling function or process. For example, control may be passed to the operation of block 424 of
The processor 912 of
The system memory 924 may include any desired type of volatile and/or non-volatile memory such as, for example, static random access memory (SRAM), dynamic random access memory (DRAM), flash memory, read-only memory (ROM), etc. The mass storage memory 925 may include any desired type of mass storage device including hard disk drives, optical drives, tape storage devices, etc.
The I/O controller 922 performs functions that enable the processor 912 to communicate with peripheral input/output (I/O) devices 926 and 928 and a network interface 930 via an I/O bus 932. The I/O devices 926 and 928 may be any desired type of I/O device such as, for example, a keyboard, a video display or monitor, a mouse, etc. The network interface 930 may be, for example, an Ethernet device, an asynchronous transfer mode (ATM) device, an 802.11 device, a DSL modem, a cable modem, a cellular modem, etc. that enables the processor system 910 to communicate with another processor system.
While the memory controller 920 and the I/O controller 922 are depicted in
Although certain methods, apparatus, and articles of manufacture have been described herein, the scope of coverage of this patent is not limited thereto. To the contrary, this patent covers all methods, apparatus, and articles of manufacture fairly falling within the scope of the appended claims either literally or under the doctrine of equivalents.