none
Detect Virtual Machine and Logical Processor/Processor Socket ID mapping using Powershell RRS feed

  • Question

  • When I do this:

    if ((pPipe = _wpopen(L"powershell -Command \"Get-Counter '\\Hyper-V VM VID Partition(*)\\*'\"", L"rt")) == NULL) exit(1);

    I get this output wherein the VM is mapped to its preferred Numa Node index (Socket ID):

    \\win-3t40ilvkkvh\hyper-v vm vid partition(lg5)\remote physical pages : 0
    \\win-3t40ilvkkvh\hyper-v vm vid partition(lg5)\preferred numa node index : 0
    \\win-3t40ilvkkvh\hyper-v vm vid partition(lg5)\physical pages allocated : 264200
    \\win-3t40ilvkkvh\hyper-v vm vid partition(lg2)\remote physical pages : 0
    \\win-3t40ilvkkvh\hyper-v vm vid partition(lg2)\preferred numa node index : 1
    \\win-3t40ilvkkvh\hyper-v vm vid partition(lg2)\physical pages allocated : 264200

    My question is how can I get the mapping between the VM and Logical processor. If some kind soul could answer, I would be grateful. 

    Ex: VM LG5 is mapped to LP1 of Socket0(numa node) or VM LG2 is mapped to LP0 of Socket 1

    thanks

    ananda



    • Edited by ananda vardhana Friday, October 11, 2019 8:42 PM
    • Moved by jrv Friday, October 11, 2019 9:04 PM Better forum
    Friday, October 11, 2019 3:55 PM

Answers

  • Virtual CPUs are not locked to specific physical cores. Even the NUMA node is only "preferred". You have no guarantee that any given vCPU will get a time slice on the same physical core that ran its previous slice.

    Eric Siron
    Altaro Hyper-V Blog
    I am an independent contributor, not an Altaro employee. I accept all responsibility for the content of my posts. You accept all responsibility for any actions that you take based on the content of my posts.

    There is a problem with this as that information is not exposed to user mode processes though any performance counters.  You can get the total and average time per cpu8 but that is the limit.  To know the exact cpu for a thread would require the thread to log that information which would be very disruptive and inefficient.  Remember that only threads are scheduled.  A process is just a container and memory map that threads run  with.  There is no "process" that runs.  A process with one thread is still only scheduled as a thread.

    Perhaps a better question is why do you think you need to know this.  There are likely other ways to get the information you need.

    There used to be a good writeup on how the scheduler works.  I haven't seen a new one since WS2003 but I am sure the major algorithm has not changed greatly.  The rule is that a process is only scheduled on one cpu and all threads are assigned to the same cpu.  This would be the most efficient method as moving a thread is costly so Windows doesn't like to move threads.  Processes written to multiple CPUs like SQLServer will alter this by assigning sub processes to multiple CPUs and may adjust thread location as required but once a thread is executing I do not believe it will be moved although the system can move any thread any time it needs to except when the thread is bound to one cpu from creation.  Since all b ut the main thread of a process can start and be destroyed faster than we can capture them knowing about specific thread is nearly impossible.  Only the main thread can be viewed since it exists through the whole lifecycle of a process. 

    Here are all of the per-process counters:

    PS C:\Users\jvierra> Get-counter -ListSet process | select -expand Paths
    \Process(*)\% Processor Time
    \Process(*)\% User Time
    \Process(*)\% Privileged Time
    \Process(*)\Virtual Bytes Peak
    \Process(*)\Virtual Bytes
    \Process(*)\Page Faults/sec
    \Process(*)\Working Set Peak
    \Process(*)\Working Set
    \Process(*)\Page File Bytes Peak
    \Process(*)\Page File Bytes
    \Process(*)\Private Bytes
    \Process(*)\Thread Count
    \Process(*)\Priority Base
    \Process(*)\Elapsed Time
    \Process(*)\ID Process
    \Process(*)\Creating Process ID
    \Process(*)\Pool Paged Bytes
    \Process(*)\Pool Nonpaged Bytes
    \Process(*)\Handle Count
    \Process(*)\IO Read Operations/sec
    \Process(*)\IO Write Operations/sec
    \Process(*)\IO Data Operations/sec
    \Process(*)\IO Other Operations/sec
    \Process(*)\IO Read Bytes/sec
    \Process(*)\IO Write Bytes/sec
    \Process(*)\IO Data Bytes/sec
    \Process(*)\IO Other Bytes/sec
    \Process(*)\Working Set - Private
    PS C:\Users\jvierra>
    If you list all of the VM counters you will not likely see much more.  'Thread" ae only exposed as the total number of current threads but no detailed thread info.

    There ae tools in the SDK that can get more info by thread but it is transient and cannot likely catch transient threads.
    ProcessExplorer can get all process threads and can give some thread info.  Even ProcessExplorer cannot tell us which CPU a thread is running on or assigned to.


    \_(ツ)_/

    Saturday, October 12, 2019 12:05 AM

All replies

  • Use the included "numa node index" as each virtual processor should be associated with a numa node.


    \_(ツ)_/

    Friday, October 11, 2019 9:01 PM
  • I have a system with two physical sockets S1 and S2. Each have 4 cores C0, C1, C2 and C3 and each core has 2 Logical Processor LP0 and LP1. The Virtual Processor assigned to the VM ultimately has to run on a Sx/Cx/LPx. So I want that mapping which VMx is mapped to which Sx/Cx/LPx. Right now Powershell is telling me my VM is running on a particular Numa Node which I call as Socket ID which is same as the physical processor package. I hope Powershell has the command which will map Cx and LPx too.  In the example VM0 is mapped to S1/C3/LP1 and VM1 is mapped to S0/C0/LP0


    Friday, October 11, 2019 9:55 PM
  • Virtual CPUs are not locked to specific physical cores. Even the NUMA node is only "preferred". You have no guarantee that any given vCPU will get a time slice on the same physical core that ran its previous slice.

    Eric Siron
    Altaro Hyper-V Blog
    I am an independent contributor, not an Altaro employee. I accept all responsibility for the content of my posts. You accept all responsibility for any actions that you take based on the content of my posts.

    Friday, October 11, 2019 10:59 PM
  • Yes fully agreed, but I would like to know at a given time slice what are the mapping. So when ever I run what ever the PowerShell command be, it should tell at this instance this is the mapping. In the next time instance it might be different, that is ok I dont care. Thanks. 
    Friday, October 11, 2019 11:35 PM
  • I've never even heard of a system to track individual time slices on any platform. That sounds exorbitantly expensive. I'm struggling to envision a use case even if you could do such a thing.

    Eric Siron
    Altaro Hyper-V Blog
    I am an independent contributor, not an Altaro employee. I accept all responsibility for the content of my posts. You accept all responsibility for any actions that you take based on the content of my posts.

    • Proposed as answer by jrv Saturday, October 12, 2019 12:06 AM
    Friday, October 11, 2019 11:58 PM
  • Virtual CPUs are not locked to specific physical cores. Even the NUMA node is only "preferred". You have no guarantee that any given vCPU will get a time slice on the same physical core that ran its previous slice.

    Eric Siron
    Altaro Hyper-V Blog
    I am an independent contributor, not an Altaro employee. I accept all responsibility for the content of my posts. You accept all responsibility for any actions that you take based on the content of my posts.

    There is a problem with this as that information is not exposed to user mode processes though any performance counters.  You can get the total and average time per cpu8 but that is the limit.  To know the exact cpu for a thread would require the thread to log that information which would be very disruptive and inefficient.  Remember that only threads are scheduled.  A process is just a container and memory map that threads run  with.  There is no "process" that runs.  A process with one thread is still only scheduled as a thread.

    Perhaps a better question is why do you think you need to know this.  There are likely other ways to get the information you need.

    There used to be a good writeup on how the scheduler works.  I haven't seen a new one since WS2003 but I am sure the major algorithm has not changed greatly.  The rule is that a process is only scheduled on one cpu and all threads are assigned to the same cpu.  This would be the most efficient method as moving a thread is costly so Windows doesn't like to move threads.  Processes written to multiple CPUs like SQLServer will alter this by assigning sub processes to multiple CPUs and may adjust thread location as required but once a thread is executing I do not believe it will be moved although the system can move any thread any time it needs to except when the thread is bound to one cpu from creation.  Since all b ut the main thread of a process can start and be destroyed faster than we can capture them knowing about specific thread is nearly impossible.  Only the main thread can be viewed since it exists through the whole lifecycle of a process. 

    Here are all of the per-process counters:

    PS C:\Users\jvierra> Get-counter -ListSet process | select -expand Paths
    \Process(*)\% Processor Time
    \Process(*)\% User Time
    \Process(*)\% Privileged Time
    \Process(*)\Virtual Bytes Peak
    \Process(*)\Virtual Bytes
    \Process(*)\Page Faults/sec
    \Process(*)\Working Set Peak
    \Process(*)\Working Set
    \Process(*)\Page File Bytes Peak
    \Process(*)\Page File Bytes
    \Process(*)\Private Bytes
    \Process(*)\Thread Count
    \Process(*)\Priority Base
    \Process(*)\Elapsed Time
    \Process(*)\ID Process
    \Process(*)\Creating Process ID
    \Process(*)\Pool Paged Bytes
    \Process(*)\Pool Nonpaged Bytes
    \Process(*)\Handle Count
    \Process(*)\IO Read Operations/sec
    \Process(*)\IO Write Operations/sec
    \Process(*)\IO Data Operations/sec
    \Process(*)\IO Other Operations/sec
    \Process(*)\IO Read Bytes/sec
    \Process(*)\IO Write Bytes/sec
    \Process(*)\IO Data Bytes/sec
    \Process(*)\IO Other Bytes/sec
    \Process(*)\Working Set - Private
    PS C:\Users\jvierra>
    If you list all of the VM counters you will not likely see much more.  'Thread" ae only exposed as the total number of current threads but no detailed thread info.

    There ae tools in the SDK that can get more info by thread but it is transient and cannot likely catch transient threads.
    ProcessExplorer can get all process threads and can give some thread info.  Even ProcessExplorer cannot tell us which CPU a thread is running on or assigned to.


    \_(ツ)_/

    Saturday, October 12, 2019 12:05 AM
  • I've never even heard of a system to track individual time slices on any platform. That sounds exorbitantly expensive. I'm struggling to envision a use case even if you could do such a thing.

    Eric Siron
    Altaro Hyper-V Blog
    I am an independent contributor, not an Altaro employee. I accept all responsibility for the content of my posts. You accept all responsibility for any actions that you take based on the content of my posts.

    I am certain the SDK has tools that may be able to do this but it is not an easy thing to set up and, as you noted, likely very disruptive.


    \_(ツ)_/

    Saturday, October 12, 2019 12:07 AM
  • Hi,

    Was your issue resolved?

     

    If you resolved it using the following solution, please "mark it as answer" to help other community members find the helpful reply quickly.

    If you resolve it using your own solution, please share your experience and solution here. It will be very beneficial for other community members who have similar questions.

    If no, please reply and tell us the current situation in order to provide further help.

     

    Best Regards,

    Lily


    Please remember to mark the replies as answers if they help.
    If you have feedback for TechNet Subscriber Support, contact

    Monday, October 14, 2019 7:31 AM
  • Sorry for getting back late was out of Internet over the weekend. The reason why I am interested in is to garnish as mush information as possible of a VM when it does not perform as expected. Sorry for being vague I can't give out more details. This collected info will help us analyse the deviation in its behavior and the overall affect on the whole system. The more info collected the better it is. 

    Lily, your detailed explanation was very good, informative and I feel you have answered my question. Basically I did not want to give up without trying all possible means of deep probing. Yes saving the VM/VP mapping information would be very expensive. As you said all that I could get was time and count values not any mapping related info. So I guess I should be happy with what I have that is Socket ID. 

    JRV thanks for your comments too. 

    Best Regards and Thanks

    ananda

     
    Monday, October 14, 2019 3:03 PM
  • So I guess I should be happy with what I have that is Socket ID.

    Understand that the socket ID that you pulled tells you NOTHING about where a VM has been been running. It ONLY tells you where it WANTS to run. If the scheduler decides that it can't reasonably operate the vCPU on the desired NUMA node, it will happily shift it to another and not tell you about it. The approach that you're taking will not yield valuable information about performance. Your time is better spent watching the various hypervisor processor counters (Hyper-V Hypervisor Virtual Processor is a great place to start).


    Eric Siron
    Altaro Hyper-V Blog
    I am an independent contributor, not an Altaro employee. I accept all responsibility for the content of my posts. You accept all responsibility for any actions that you take based on the content of my posts.

    Monday, October 14, 2019 3:27 PM