Hyper-Threading and ProcessorAffinity

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • [Yosi]

    #1

    Hyper-Threading and ProcessorAffinity

    I create new thread as following:
    Thread mThread = new Thread(new ThreadStart(m_C lassThread.Go)) ;
    In my system I have 2 Process devices ,(CPU0 and CPU1) , I want to create 3
    Threads, 2 of those thread to run in CPU0 and the last one in CPU1 , I get
    some advice to use the ProcessThread.P rocessorAffinit y which seems OK to me .
    The problem is how and where to use it ?
    Should I change the :
    Thread mThread = new Thread(new ThreadStart(m_C lassThread.Go)) ;
    mThread.Start() ;
    How to do that . is there any whay to do something like :
    SetProcessorAff inity( ref hthread, int mask) ?????
  • Nicholas Paldino [.NET/C# MVP]

    #2
    Re: Hyper-Threading and ProcessorAffini ty

    Yosi,

    You could try and do it, however, this isn't a good idea in .NET. In
    ..NET, the Thread class doesn't represent a physical thread. It is a logical
    thread of execution. Because of this, you don't know how the current thread
    you are running on maps to the physical OS thread that it is running on.

    If you really need to do this, I would perform your tasks in unmanaged
    code and set the affinity there.

    Hope this helps.


    --
    - Nicholas Paldino [.NET/C# MVP]
    - mvp@spam.guard. caspershouse.co m

    "[Yosi]" <Yosi@discussio ns.microsoft.co m> wrote in message
    news:FE93A208-4CE0-4D2E-B6D7-0350F7B50A52@mi crosoft.com...[color=blue]
    >I create new thread as following:
    > Thread mThread = new Thread(new ThreadStart(m_C lassThread.Go)) ;
    > In my system I have 2 Process devices ,(CPU0 and CPU1) , I want to create
    > 3
    > Threads, 2 of those thread to run in CPU0 and the last one in CPU1 , I
    > get
    > some advice to use the ProcessThread.P rocessorAffinit y which seems OK to
    > me .
    > The problem is how and where to use it ?
    > Should I change the :
    > Thread mThread = new Thread(new ThreadStart(m_C lassThread.Go)) ;
    > mThread.Start() ;
    > How to do that . is there any whay to do something like :
    > SetProcessorAff inity( ref hthread, int mask) ?????[/color]


    Comment

    • Willy Denoyette [MVP]

      #3
      Re: Hyper-Threading and ProcessorAffini ty


      "[Yosi]" <Yosi@discussio ns.microsoft.co m> wrote in message
      news:FE93A208-4CE0-4D2E-B6D7-0350F7B50A52@mi crosoft.com...[color=blue]
      >I create new thread as following:
      > Thread mThread = new Thread(new ThreadStart(m_C lassThread.Go)) ;
      > In my system I have 2 Process devices ,(CPU0 and CPU1) , I want to create
      > 3
      > Threads, 2 of those thread to run in CPU0 and the last one in CPU1 , I
      > get
      > some advice to use the ProcessThread.P rocessorAffinit y which seems OK to
      > me .
      > The problem is how and where to use it ?
      > Should I change the :
      > Thread mThread = new Thread(new ThreadStart(m_C lassThread.Go)) ;
      > mThread.Start() ;
      > How to do that . is there any whay to do something like :
      > SetProcessorAff inity( ref hthread, int mask) ?????[/color]

      Here is how you can do it.

      using System;
      using System.Runtime. InteropServices ;

      using System.Diagnost ics;
      using System.Threadin g;
      namespace Tester
      {
      class Program
      {
      [DllImport("kern el32")]
      static extern int GetCurrentThrea dId();
      static void Main()
      {
      Thread t = new Thread(
      new ThreadStart(DoW ork));
      t.Start();
      t.Join();
      }
      static void DoWork()
      {
      foreach(Process Thread pt in Process.GetCurr entProcess().Th reads)
      {
      int utid = GetCurrentThrea dId();
      if (utid == pt.Id)
      {
      pt.ProcessorAff inity = (IntPtr)(1); // Set affinity for this
      thread to CPU #1
      Console.WriteLi ne("Set");
      }
      }
      }
      }
      }


      Willy.


      Comment

      • TT \(Tom Tempelaere\)

        #4
        Re: Hyper-Threading and ProcessorAffini ty

        Willy,

        "Willy Denoyette [MVP]" <willy.denoyett e@telenet.be> schreef in bericht
        news:uR1G6fu6FH A.472@TK2MSFTNG P15.phx.gbl...
        [...][color=blue][color=green]
        >> How to do that . is there any whay to do something like :
        >> SetProcessorAff inity( ref hthread, int mask) ?????[/color]
        >
        > Here is how you can do it.
        >
        > using System;
        > using System.Runtime. InteropServices ;
        >
        > using System.Diagnost ics;
        > using System.Threadin g;
        > namespace Tester
        > {
        > class Program
        > {
        > [DllImport("kern el32")]
        > static extern int GetCurrentThrea dId();
        > static void Main()
        > {
        > Thread t = new Thread(
        > new ThreadStart(DoW ork));
        > t.Start();
        > t.Join();
        > }
        > static void DoWork()
        > {
        > foreach(Process Thread pt in Process.GetCurr entProcess().Th reads)
        > {
        > int utid = GetCurrentThrea dId();[/color]

        Does GetCurrentThrea d return the same ID each time in this loop? I heard
        that .NET threads are logical threads, not physical threads. So technically,
        wouldn't it be possible that another physical thread starts executing the
        logical thread?
        [color=blue]
        > if (utid == pt.Id)
        > {
        > pt.ProcessorAff inity = (IntPtr)(1); // Set affinity for this
        > thread to CPU #1
        > Console.WriteLi ne("Set");
        > }
        > }
        > }
        > }
        > }
        >
        > Willy.[/color]

        Kind regards,
        --
        Tom Tempelaere.


        Comment

        • Willy Denoyette [MVP]

          #5
          Re: Hyper-Threading and ProcessorAffini ty


          "TT (Tom Tempelaere)" </\/_0_$P@/\/\titi____AThotm ailD.Tcom/\/\@P$_0_/\/>
          wrote in message news:VC7ff.5123 4$hw6.3013678@p hobos.telenet-ops.be...[color=blue]
          > Willy,
          >
          > "Willy Denoyette [MVP]" <willy.denoyett e@telenet.be> schreef in bericht
          > news:uR1G6fu6FH A.472@TK2MSFTNG P15.phx.gbl...
          > [...][color=green][color=darkred]
          >>> How to do that . is there any whay to do something like :
          >>> SetProcessorAff inity( ref hthread, int mask) ?????[/color]
          >>
          >> Here is how you can do it.
          >>
          >> using System;
          >> using System.Runtime. InteropServices ;
          >>
          >> using System.Diagnost ics;
          >> using System.Threadin g;
          >> namespace Tester
          >> {
          >> class Program
          >> {
          >> [DllImport("kern el32")]
          >> static extern int GetCurrentThrea dId();
          >> static void Main()
          >> {
          >> Thread t = new Thread(
          >> new ThreadStart(DoW ork));
          >> t.Start();
          >> t.Join();
          >> }
          >> static void DoWork()
          >> {
          >> foreach(Process Thread pt in Process.GetCurr entProcess().Th reads)
          >> {
          >> int utid = GetCurrentThrea dId();[/color]
          >
          > Does GetCurrentThrea d return the same ID each time in this loop? I heard
          > that .NET threads are logical threads, not physical threads. So
          > technically, wouldn't it be possible that another physical thread starts
          > executing the logical thread?
          >[color=green]
          >> if (utid == pt.Id)
          >> {
          >> pt.ProcessorAff inity = (IntPtr)(1); // Set affinity for this
          >> thread to CPU #1
          >> Console.WriteLi ne("Set");
          >> }
          >> }
          >> }
          >> }
          >> }
          >>
          >> Willy.[/color]
          >
          > Kind regards,
          > --
          > Tom Tempelaere.
          >[/color]

          Tom,

          I'm not using any Logical thread Id here, both 'GetCurrentThre adId' and
          'pt.Id ' return the OS thread id. I'm using the first to get the current OS
          thread ID and use the ID to search the corresponding thread in the
          ProcessThreadCo llection, once I have the ProcessThread I can use
          ProcessorAffini ty to set the affinity mask. As long as the thread runs it
          keeps the same Id (and the same logical thread which I don't care).
          I ran this on an 8 way box, funny how you can disturb the system by playing
          with this :-)). IMO this API (ProcessorAffin ity) shouldnt be used from
          managed code, honestly I don't see why it was included in the framework,
          while other more important features are still missing, cheep to implement I
          guess.

          Willy.


          Comment

          • TT \(Tom Tempelaere\)

            #6
            Re: Hyper-Threading and ProcessorAffini ty

            Hi Willy,

            "Willy Denoyette [MVP]" <willy.denoyett e@telenet.be> schreef in bericht
            news:%23LxOur86 FHA.1080@TK2MSF TNGP10.phx.gbl. ..[color=blue]
            >
            > "TT (Tom Tempelaere)" </\/_0_$P@/\/\titi____AThotm ailD.Tcom/\/\@P$_0_/\/>
            > wrote in message news:VC7ff.5123 4$hw6.3013678@p hobos.telenet-ops.be...[color=green]
            >> Willy,
            >>
            >> "Willy Denoyette [MVP]" <willy.denoyett e@telenet.be> schreef in bericht
            >> news:uR1G6fu6FH A.472@TK2MSFTNG P15.phx.gbl...
            >> [...][color=darkred]
            >>>> How to do that . is there any whay to do something like :
            >>>> SetProcessorAff inity( ref hthread, int mask) ?????
            >>>
            >>> Here is how you can do it.
            >>>
            >>> using System;
            >>> using System.Runtime. InteropServices ;
            >>>
            >>> using System.Diagnost ics;
            >>> using System.Threadin g;
            >>> namespace Tester
            >>> {
            >>> class Program
            >>> {
            >>> [DllImport("kern el32")]
            >>> static extern int GetCurrentThrea dId();
            >>> static void Main()
            >>> {
            >>> Thread t = new Thread(
            >>> new ThreadStart(DoW ork));
            >>> t.Start();
            >>> t.Join();
            >>> }
            >>> static void DoWork()
            >>> {
            >>> foreach(Process Thread pt in Process.GetCurr entProcess().Th reads)
            >>> {
            >>> int utid = GetCurrentThrea dId();[/color]
            >>
            >> Does GetCurrentThrea d return the same ID each time in this loop? I heard
            >> that .NET threads are logical threads, not physical threads. So
            >> technically, wouldn't it be possible that another physical thread starts
            >> executing the logical thread?
            >>[color=darkred]
            >>> if (utid == pt.Id)
            >>> {
            >>> pt.ProcessorAff inity = (IntPtr)(1); // Set affinity for this
            >>> thread to CPU #1
            >>> Console.WriteLi ne("Set");
            >>> }
            >>> }
            >>> }
            >>> }
            >>> }
            >>>
            >>> Willy.[/color]
            >>
            >> Kind regards,
            >> --
            >> Tom Tempelaere.
            >>[/color]
            >
            > Tom,
            >
            > I'm not using any Logical thread Id here, both 'GetCurrentThre adId' and
            > 'pt.Id ' return the OS thread id. I'm using the first to get the current
            > OS thread ID and use the ID to search the corresponding thread in the
            > ProcessThreadCo llection, once I have the ProcessThread I can use
            > ProcessorAffini ty to set the affinity mask. As long as the thread runs it
            > keeps the same Id (and the same logical thread which I don't care).
            > I ran this on an 8 way box, funny how you can disturb the system by
            > playing with this :-)). IMO this API (ProcessorAffin ity) shouldnt be used
            > from managed code, honestly I don't see why it was included in the
            > framework, while other more important features are still missing, cheep to
            > implement I guess.
            >
            > Willy.[/color]

            What I meant is that .NET has logical threads, the OS has physical threads
            (if I read that correctly). Logical threads are executed on physical
            threads, but I don't know if they need to execute on the same physical
            thread each time the logical thread's time-slice phases in.

            Actually I don't know the real details about how .NET framework implements
            threading on WinOS. But if the logical thread can be executed by different
            physical threads, then if the logical thread phases out right after the call
            to GetCurrentThrea dId, the logical thread could be rescheduled on a
            different physical thread so the ID you got is no longer the correct one.
            This is just my train of thought now, considering the difference between
            physical and logical threads.

            A sketch of my thoughts

            // --> logical .NET thread [L_X] scheduled on physical WinOS thread [P_X]
            int utId = GetCurrentThrea dId( ); // utId == P_X
            // --> the logical thread ends its time slice
            ....
            // --> logical .NET thread [L_X] scheduled on physical WinOS thread [P_Y]
            if (utId == pt.Id) // utId != P_Y

            I'm not saying that this is possible, as I said I know too little of the
            internal details. I think that the logical and the physical threads are
            tightly coupled in the implementation of MS's .NET framework, but should
            they be? Why did they make the distinction between logical and physical
            threads otherwise? Does the documentation say that a logical thread is
            always scheduled on the same physical thread?

            Kind regards,
            --
            Tom Tempelaere.


            Comment

            • Willy Denoyette [MVP]

              #7
              Re: Hyper-Threading and ProcessorAffini ty

              Tom, see inline...

              Willy.

              "TT (Tom Tempelaere)" </\/_0_$P@/\/\titi____AThotm ailD.Tcom/\/\@P$_0_/\/>
              wrote in message news:cHoff.5169 2$1C6.3033201@p hobos.telenet-ops.be...
              [color=blue][color=green]
              >> Tom,
              >>
              >> I'm not using any Logical thread Id here, both 'GetCurrentThre adId' and
              >> 'pt.Id ' return the OS thread id. I'm using the first to get the current
              >> OS thread ID and use the ID to search the corresponding thread in the
              >> ProcessThreadCo llection, once I have the ProcessThread I can use
              >> ProcessorAffini ty to set the affinity mask. As long as the thread runs it
              >> keeps the same Id (and the same logical thread which I don't care).
              >> I ran this on an 8 way box, funny how you can disturb the system by
              >> playing with this :-)). IMO this API (ProcessorAffin ity) shouldnt be used
              >> from managed code, honestly I don't see why it was included in the
              >> framework, while other more important features are still missing, cheep
              >> to implement I guess.
              >>
              >> Willy.[/color]
              >
              > What I meant is that .NET has logical threads, the OS has physical threads
              > (if I read that correctly). Logical threads are executed on physical
              > threads, but I don't know if they need to execute on the same physical
              > thread each time the logical thread's time-slice phases in.
              >[/color]

              Logical thread don't execute, only physical threads do, and each logical
              thread (an object instance) is associated with a physical thread. This
              associating is fixed and exists for the lifetime of the logical thread.
              Also logical threads do not get scheduled, so they aren't "time-sliced".
              [color=blue]
              > Actually I don't know the real details about how .NET framework implements
              > threading on WinOS. But if the logical thread can be executed by different
              > physical threads, then if the logical thread phases out right after the
              > call to GetCurrentThrea dId, the logical thread could be rescheduled on a
              > different physical thread so the ID you got is no longer the correct one.
              > This is just my train of thought now, considering the difference between
              > physical and logical threads.
              >[/color]

              No, as said before a logical thread is associated with a physical thread
              which ceases to exist when the thread procedure exists. Note, I'm not
              talking about Threadpool threads, only regular self started threads.
              [color=blue]
              > A sketch of my thoughts
              >
              > // --> logical .NET thread [L_X] scheduled on physical WinOS thread [P_X]
              > int utId = GetCurrentThrea dId( ); // utId == P_X
              > // --> the logical thread ends its time slice
              > ...
              > // --> logical .NET thread [L_X] scheduled on physical WinOS thread [P_Y]
              > if (utId == pt.Id) // utId != P_Y
              >
              > I'm not saying that this is possible, as I said I know too little of the
              > internal details. I think that the logical and the physical threads are
              > tightly coupled in the implementation of MS's .NET framework, but should
              > they be? Why did they make the distinction between logical and physical
              > threads otherwise? Does the documentation say that a logical thread is
              > always scheduled on the same physical thread?
              >[/color]

              Again, a logical thread doesn't get scheduled, it's a CLR data structure not
              an active OS object, the CLR keeps track of the asociations and the OS
              threads keeps a reference (in TLS) to the corresponding CLR thread's data
              structure.
              The distinction is simply an abstraction, at the application level you
              shouldn't care about the underlying implementation, that way the CLI
              implementor has the freedom to implement threading as he sees fit (depending
              on the available OS platform services). For instance the CLI (or an Hosting
              process like SQL2005) could associate a Fiber instead of a OS thread to a
              logical thread.
              In such a case, multiple logical threads would run on the same OS thread,
              and these logical threads would end on the same CPU if you set the OS thread
              affinity.

              Willy.


              Comment

              • chuckb@empiricdesign.com

                #8
                Re: Hyper-Threading and ProcessorAffini ty

                I can think of a couple of reasons you might/may want to set processor
                affinity (even from managed code).

                1. You're selling an application that you license by the processor.
                They've only bought a one-processor license, so that's all they get.

                2. You are USING an application that you license by the processor (SQL
                Server) and you're not using all the processors for it. You might want
                to have your application running on the non-SQL Server processors so
                that it doesn't slow down the SQL Server ones. Memory would be a
                separate issue, of course.

                Chuck

                Comment

                • Willy Denoyette [MVP]

                  #9
                  Re: Hyper-Threading and ProcessorAffini ty


                  <chuckb@empiric design.com> wrote in message
                  news:1134759058 .169665.3370@f1 4g2000cwb.googl egroups.com...[color=blue]
                  >I can think of a couple of reasons you might/may want to set processor
                  > affinity (even from managed code).
                  >
                  > 1. You're selling an application that you license by the processor.
                  > They've only bought a one-processor license, so that's all they get.
                  >[/color]

                  HT cores are not physical CPU's! You ain't gonna license your application
                  per logical CPU do you?
                  [color=blue]
                  > 2. You are USING an application that you license by the processor (SQL
                  > Server) and you're not using all the processors for it. You might want
                  > to have your application running on the non-SQL Server processors so
                  > that it doesn't slow down the SQL Server ones. Memory would be a
                  > separate issue, of course.
                  >[/color]
                  Same here SQL server license is not per logical CPU, an HT P4 for instance
                  is considered one single CPU for SQL server (and for the Windows OS).

                  Willy.


                  Comment

                  Working...