profiler/src/llm/skill.optimization.md
The user may ask you to optimize a particular functionality, routine, or code fragment. While doing so, the user may include attachments of various types:
You should try to find where the optimization opportunities are. Note that some code may already be optimized very well, and there may be little or nothing left to gain.
When a source code function is compiled, the compiler may inline multiple auxiliary functions into the produced machine code block. This block is called a symbol. The symbol may contain multiple source-level functions (some of which may be repeated multiple times), which may come from multiple source files.
The assembly instruction listing of a symbol must be mapped to the source code. The assembly attachment contains the code itself, and an array of source files named files. The format of an assembly line is:
fileIdx:line:offset:cost:callCost:assembly
To identify the source file name of any assembly instruction, you must access files[fileIdx]. The fileIdx value is strictly internal and should never be presented to the user. Always show the source file name and line number in your answers. Since symbols can be constructed from multiple source files, you must specify both the source file name and line number, or user won't know which file you refer to.
The offset value represents the byte offset at which the machine instruction lies in the symbol code.
The cost value shows how much time the CPU spent executing the given machine instruction. If the cost is not present, the profiler recorded no activity for the given instruction. The callCost value shows how much time was spent executing the called external functions. The cost values are percentages relative to the total execution cost of an entire symbol, including external function calls.
The assembly value is the actual disassembled machine code. It may also contain a comment with:
label, for example .L6.destination.The measurements present in the attachment may be slightly imprecise due to the way the profiler infrastructure or the CPU works, especially considering out-of-order architectures. As a result, some cost value may be wrongly attributed to the instruction in the immediate vicinity of the instruction that produced the cost.
Take the following example:
5% mov rax, [rbx]
40% inc rax
The first instruction that loads the value from memory is the high-latency one, but it can be dispatched for execution fairly quickly. The second instruction, which needs the output of the first instruction, is actually very fast to execute but is blocked by the slow memory access of the first instruction, taking the majority of the cost on itself.
A careful investigation of the cost attribution is thus needed.
Analyzing a user program can be done in two complementary ways.
When looking at code, you may find many places that use inefficient algorithms or implementations. While pointing out such cases may sometimes be useful, you must check whether the problematic code is actually on the hot path, as indicated by the profiling data included with the disassembly. The profiling data the user provides are highly targeted at specific workflows, and the primary optimization target should be the code that was actually executing, not something that could run theoretically. Avoid including optimization advice for code paths that might run but did not.
When reasoning about the performance of a symbol, you should look at the environment where it is used. You can do this by:
The entry call stacks can be queried in three modes: