Intel® VTune™ Profiler

Cookbook

ID 766316
Date 6/03/2024
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

Profiling a .NET* Core Application

Profile .NET Core dynamic code with Intel® VTune™ Profiler. Locate performance hot spots in your code and optimize as needed.

Ingredients

This section lists the hardware and software tools used for the performance analysis scenario.

  • Application: A sample C# application that adds all the elements of an integer List. The application in this recipe is used for demonstration only and it is not available for download.

  • Tools:

  • Operating system: Microsoft* Windows* 11

  • CPU: Intel microarchitecture code named Alder Lake

Prepare Your Application for Analysis

  1. Open a new command window for the .NET environment variables to take effect. Make sure that you have installed .NET Core 7.0:

    dotnet --version
  2. Create a new listadd directory for the application:

    mkdir C:\listadd
    > cd C:\listadd
  3. Enter dotnet new console to create a new skeleton project with the following structure:

  4. Replace the contents of Program.cs in the listadd folder with C# code that adds the elements of an integer List:

    using System;
    using System.Linq;
    using System.Collections.Generic;
    
    namespace listadd
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Starting calculation...");            
                List<int> numbers = Enumerable.Range(1,10000).ToList();
                for (int i =0; i < 100000; i ++)
                {
                    ListAdd(numbers);
                }
                
                Console.WriteLine("Calculation complete");            
            }
    
            static int ListAdd(List<int> candidateList)
            {
                int result = 0;
                foreach (int item in candidateList)
                {
                    result += item;
                }
                
                return result;
            }        
        }
    }
  5. Create listadd.dll in the C:\listadd\bin\x64\Release\net7.0 folder:

    dotnet build -c Release
  6. Run the sample application:

    dotnet C:\listadd\bin\x64\Release\net7.0\listadd.dll

Run Hotspots Analysis

  1. Run Intel VTune Profiler with administrator privileges.

  2. Click the New Project button on the toolbar. Specify a name for the new project, for example: dotnet.

  3. In the Analysis Target window, select local host and Launch Application target type from the left pane.

  4. In the Launch Application pane, specify the application to analyze:

    • Application: C:\Program Files\dotnet\dotnet.exe

    • Application parameters: C:\listadd\bin\x64\Release\net7.0\listadd.dll

    NOTE:

    The location of dotnet.exe depends on your environment. Use the where dotnet command to find this location.

  5. In the How pane, select Hotspots analysis. Make sure to enable Hardware Event-Based Sampling and Collect Stacks options.

  6. Click Start to run the analysis.

Identify Hot Spots in the Managed Code

When the collected analysis result opens, switch to the Bottom-up tab. Set the data grouping level to Process/Module/Function/Thread/Call Stack:

Expand dotnet.exe > listadd.dll and notice that the listadd::Program::ListAdd function occupied most of the CPU Time:

Doubleclick this hot spot function to open the source view. To view the source and disassembly code side by side, click the Assembly toggle button on the toolbar:

Use the statistics per source line/assembly instruction to identify the most time-consuming code snippets (line 24 in the example above) and work on optimizations.

Optimize the Code with Loop Interchange

Intel VTune Profiler highlights the following code line as performance-critical:

foreach (int item in candidateList)

For optimization, consider using the for loop statement. Replace the contents of Program.cs with this C# code:

using System;
using System.Linq;
using System.Collections.Generic;

namespace listadd
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Starting calculation...");            
            List<int> numbers = Enumerable.Range(1,10000).ToList();
            for (int i =0; i < 100000; i ++)
            {
                ListAdd(numbers);
            }
            
            Console.WriteLine("Calculation complete");            
        }

        static int ListAdd(List<int> candidateList)
        {
            int result = 0;
            for (int i = 0; i < candidateList.Count; i++)
            {
                result += candidateList[i];
            }

            return result;
        }        
    }
}

Verify the Optimization

To verify the optimization for the updated code, repeat the Hotspots analysis.

Prior to optimization, the sample application took 511.004 ms of CPU time:

After optimization, the application ran for 430.477s, which is a 16% reduction in time over the original:

Discuss this recipe in the Analyzers community forum

NOTE: