10 Replies Latest reply on Aug 8, 2012 12:54 AM by binying

    Understanding performance counters

    chersanya

      I have a kernel, and each workitem processes tens of elements (firstly perform some computation and then global memory read + write). The profiler gave me much help in optimizing it, however I want to go further Now the profiling data looks like this (almost the same for all kernel runs):

       

      GlobalWorkSize     126720
      WorkGroupSize     256
      VGPRs     13
      FCStacks     2
      ALUInsts     6787.63
      FetchInsts     52.47
      WriteInsts     26.47
      ALUBusy     98.31
      ALUFetchRatio     129.37
      ALUPacking     72.16
      FetchSize     411503.38
      CacheHit     0.09
      FetchUnitBusy     89.44
      FetchUnitStalled     93.86
      WriteUnitStalled 0.00
      FastPath     9.19
      CompletePath     28.91
      PathUtilization     30.52
      

       

      LDS not used at all, kernel occupancy is 50% (VGPR-limited 16 waves).

      I can't understand several points here:

      • What exactly means FCStacks value? I have only one loop (for), and no if statements, but its value is two.
      • How can be ALUBusy 98% with low ALUPacking (72%)? As I see from ALUPacking, not all VLIWs are filled at full, so ALUBusy shouldn't be so close to 100%
      • FetchUnitStalled > FetchUnitBusy while it's written that FetchUnitBusy includes stalled time - how?

       

      And how to improve ALUPacking up to 100%?

        • Understanding performance counters
          nou

          ALU is counted as busy even with pure scalar code. ALU packing at 72% is quite high. you can try put code of work item into static loop for(int i=0;i<2;i++). compler will it unroll and you get quick/dirty way to vectorize code.

            • Re: Understanding performance counters
              chersanya

              I already have a static loop in the kernel, but unrolling it (either with #pragma or manually) leads to poorer performance - probably because of registers, but not sure.

              And what exactly is ALUPacking value? I think it's average of (used VLIW instructions)/(available VLIW instructions - i.e 5 in the case of VLIW5), but it is just speculation.

                • Re: Understanding performance counters
                  nou

                  from profiler manual ALUBusy - The percentage of GPUTime ALU instructions are processed.

                  and also to ALUpacking - The ALU vector packing efficiency (in percentage). This value indicates how well the Shader Compiler packs the scalar or vector ALU in your kernel to the 5-way VLIW instructions. Value range: 0% (bad) to 100% (optimal). Values below 70 percent indicate that ALU dependency chains may be preventing full utilization of the processor.

                    • Re: Understanding performance counters
                      chersanya

                      Yes, I've read this

                      But "how well (the Shader Compiler packs...)" is not a very concrete description of a counter That's why I'm asking if my guess is right (ALUPacking = [used VLIW instructions]/[available VLIW instructions - i.e 5 in the case of VLIW5]).

                      • Re: Understanding performance counters
                        binying
                        FCStacksThe size of the flow control stack used by the kernel (valid only for AMD Radeon HD 6000 series GPU devices or older). This number may affect the number of wavefronts in-flight. To reduce the stack size, reduce the amount of flow control nesting in the kernel.

                        This is from the profiler manual. Note that it is valid only for HD6000 or older

                          • Re: Understanding performance counters
                            binying

                            ALUBusy measures the percentage of GPU time ALU instructions are processed. There are many reasons for a low ALUBusy number, for example, not enough active wavefront to hide instruction latency or heavy memory access.

                            Code divergence can be measured with VALUUtilization counter if you have SI hardware.

                             

                            http://devgurus.amd.com/thread/158655

                             

                            ALUPacking mesures the ALU vector packing efficiency (in percentage). This value indicates how well the Shader Compiler packs the scalar or vector ALU in your kernel to the 5-way VLIW instructions. Value range: 0% (bad) to 100% (optimal). Values below 70 percent indicate that ALU dependency chains may be preventing full utilization of the processor.

                             

                            So I think it makes sense that  ALUBusy 98% and low ALUPacking (72%) occur at the same time.

                              • Re: Understanding performance counters
                                binying
                                FetchUnitBusyThe percentage of GPUTime the Fetch unit is active. The result includes the stall time (FetchUnitStalled). This is measured with all extra fetches and any cache or memory effects taken into account. Value range: 0% to 100% (fetch-bound).
                                FetchUnitStalledThe percentage of GPUTime the Fetch unit is stalled. Try reducing the number of fetches or reducing the amount per fetch if possible. Value range: 0% (optimal) to 100% (bad).
                                  • Re: Understanding performance counters
                                    binying

                                    how to improve ALUPacking?

                                     

                                    Use int4/float4/etc for memory accesses and total element operations, as this is the type of workload a graphics card is optimized for memory access and alu load.

                                     

                                    Try to avoid bank conflicts across the device...

                                      • Re: Understanding performance counters
                                        chersanya

                                        To be honest, your answers didn't give any new information: everything exists in the manual. But it's not 100% clear, for example let's look at FetchUnitBusy and FetchUnitStalled counters. According to the documentation, Stalled time can't be greater than Busy, but it is.

                                          • Re: Understanding performance counters
                                            binying

                                            ALUBusy is the % of time ALU isactually executing.

                                             

                                            ALUPAcking is the percentage of code that has been successfully packed into VLIW. Well, the compiler takes scalar code and generates vector or VLIW code for the hardware. Sometimes, code cannot be vectorized, this results in lower performance, e.g., you have lower ALUPacking.

                                             

                                            To improve APUPacking, you could also reduce conditional statements etc /for loops etc so that compiler can vectorize easily. But I think it is very difficult to have 100% ALUPacking.

                                             

                                            As for FetchUnitBusy and FetchUnitStalled counters, I would speculate that their relationship is sth. like that of ALUBusy and ALUPacking.