CPython Sampling Example

In this example, you will build a debug build of CPython from sources and then execute simple instructions in the Python interactive mode to obtain WindowsPerf sampling results from a CPython runtime image.


You will use sampling to determine CPython program “hot” locations provided by frequencies of PMU events specified by the user.

There are basically two models for using performance monitoring hardware:

  • the counting model, for obtaining aggregate counts of occurrences of special events
  • the sampling model, for determining the frequencies of event occurrences produced by program locations at the function, basic block, and/or instruction levels

WindowsPerf support both.

You will try two ways of sampling with WindowsPerf via the sample and record commands.


This example does not include information about the methodology used to determine the PMU events in this learning path.

Before you begin

For this learning path you will need:

CPython cross-build on an x86_64 machine targeting ARM64

CPython is an open-source project. There is native support in CPython for Windows on Arm starting with version 3.11. In this learning path you will use a debug build of CPython. For this, you will build CPython locally from sources in the debug mode on an x86_64 machine and cross-compile it for an ARM64 target.

Use the Visual Studio Developer Command Prompt for VS 2022 which is already set up in the VS environment. Go to Start and search for “Developer Command Prompt for VS 2022”. You should see a prompt as shown below:


** Visual Studio 2022 Developer Command Prompt v17.7.6
** Copyright (c) 2022 Microsoft Corporation

C:\Program Files\Microsoft Visual Studio\2022\Community>

Please use Developer Command Prompt for VS 2022 with all of the next steps.

Clone CPython source code


            git clone git@github.com:python/cpython.git

The output from this command will be similar to:


        Cloning into 'cpython'...
remote: Enumerating objects: 990145, done.
remote: Counting objects: 100% (43119/43119), done.
remote: Compressing objects: 100% (896/896), done.
remote: Total 990145 (delta 42673), reused 42290 (delta 42223), pack-reused 947026
Receiving objects: 100% (990145/990145), 527.93 MiB | 14.28 MiB/s, done.
Resolving deltas: 100% (792463/792463), done.
Updating files: 100% (4647/4647), done.


Checkout CPython at specific SHA


This step is optional, but please remember that you may encounter build issues unrelated to this example as the CPython mainline source code that you’ve just checked out is not stable. Therefore, we recommend that you check out SHA to avoid any unexpected issues and to ensure you are working off the same code base.

Use a specific CPython commit to match the sampling output in this example:


            cd cpython
git checkout 1ff81c0cb67215694f084e51c4d35ae53b9f5cf9

The output will be similar to:


        Updating files: 100% (2774/2774), done.
Note: switching to '1ff81c0cb67215694f084e51c4d35ae53b9f5cf9'.


Build CPython from sources

The folder cpython\PCbuild contains the build.bat script you will use to build CPython from sources. Build CPython with debug symbols by invoking the -d command line option and select the ARM64 target with -p ARM64.


Make sure you are using Developer Command Prompt for VS 2022.


            cd PCbuild
build.bat -d -p ARM64

The output will be similar to:


            Downloading nuget...
Installing Python via nuget...


  python.vcxproj -> C:\<path>\cpython\PCbuild\arm64\python_d.exe
  Wrote C:\<path>\cpython\PCbuild\arm64\LICENSE.txt
  pythonw.vcxproj -> C:\<path\cpython\PCbuild\arm64\pythonw_d.exe

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:59.50

The folder cpython\PCbuild\arm64 should contain all the executables built in this process. You will use python_d.exe in this example.

Setting up the ARM64 environment


All the following steps are done on a native ARM64 Windows on Arm machine.

You will now move to a Windows on Arm (ARM64) native machine and perform the following steps:

  • Copy the built CPython executables and libraries
  • Execute the CPython interactive console to make sure all is set up
Copy the prebuilt CPython to an ARM64 machine
  1. Create a new example directory on the ARM64 machine:

                mkdir LearningPath
  2. Copy the PCbuild\arm64 directory from your x86_64 build machine to the LearningPath directory on your ARM64 machine.


You can use the Remote Desktop to copy a whole directory between two Windows machines with Ctrl+C / Ctrl+V.

  1. Copy the Lib directory from your x86_64 build machine to the LearningPath directory on your ARM64 machine.

  2. Your directory structure on ARM64 machine should look like this:

Execute interactive mode to make sure all the CPython dependencies and libraries are loaded

On your Windows ARM64 machine, open a command prompt and run:


            cd LearningPath\PCbuild\arm64

You should see CPython being invoked in interactive mode:


        Python 3.12.0a6+ (heads/main:1ff81c0cb6, Mar 14 2023, 16:26:50) [MSC v.1935 64 bit (ARM64)] on win32
Type "help", "copyright", "credits" or "license" for more information.


Your environment should now be fully set up and you are ready to move on to the next step.