Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 10 Mar 2015 10:07:19 -0600
From:      Alan Somers <asomers@freebsd.org>
To:        Freddie Cash <fjwcash@gmail.com>
Cc:        "freebsd-hackers@freebsd.org" <freebsd-hackers@freebsd.org>, "lokadamus@gmx.de" <lokadamus@gmx.de>, "Pokala, Ravi" <rpokala@panasas.com>, Rui Paulo <rpaulo@me.com>
Subject:   Re: detecting hyperthreading
Message-ID:  <CAOtMX2i6MOyHKc08GgyMgsxWcCWUUCTd2qHSnY=9WaZhUm2xdA@mail.gmail.com>
In-Reply-To: <CAOjFWZ594OKAZ95ybegKiu%2BKr4-YeEZfJGVmv1obhxeZjVVbNA@mail.gmail.com>
References:  <D12358C5.12F652%rpokala@panasas.com> <9F2E1411-B517-4BC8-AF61-BB15EE35083C@me.com> <D123957A.12F6CA%rpokala@panasas.com> <54FF1343.1020705@gmx.de> <D1246191.12F7D6%rpokala@panasas.com> <CAOjFWZ594OKAZ95ybegKiu%2BKr4-YeEZfJGVmv1obhxeZjVVbNA@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Mar 10, 2015 at 10:02 AM, Freddie Cash <fjwcash@gmail.com> wrote:
> On Tue, Mar 10, 2015 at 8:56 AM, Pokala, Ravi <rpokala@panasas.com> wrote:
>
>> -----Original Message-----
>> From: "lokadamus@gmx.de" <lokadamus@gmx.de>
>> Date: 2015-03-10, Tuesday at 08:52
>> To: Ravi Pokala <rpokala@panasas.com>, Rui Paulo <rpaulo@me.com>
>> Cc: "freebsd-hackers@freebsd.org" <freebsd-hackers@freebsd.org>
>> Subject: Re: detecting hyperthreading
>>
>> >Have you look at dmesg?
>> >My system is a P4 with HTT.
>> >dmesg |more
>> [...]
>> >CPU: Intel(R) Pentium(R) 4 CPU 3.00GHz (3000.00-MHz 686-class CPU)
>> >  Origin = "GenuineIntel"  Id = 0xf29  Family = 0xf  Model = 0x2
>> >Stepping = 9
>> >
>> >Features=0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,M
>> >CA,CMOV,PAT,PSE36,CLFLUSH,DTS,ACPI,MMX,FXSR,SSE,SSE2,SS,HTT,TM,PBE>
>> >  Features2=0x4400<CNXT-ID,xTPR>
>>
>> Of course. :-)
>>
>> But there are two problems:
>>
>> (1) That just tells me HTT is supported by the CPU, not that if kernel is
>> using it.
>> (2) It's difficult to parse.
>>
>> Of the two, (1) is the bigger concern for my use-case.
>>
>
> 6 lines or so below the Features line shows the kernel loading "cpu0
> (BSP)", and then "cpu1 (AP/HT)".
>
> Compare that to a system without HTT, where any extra cpus only show "(AP)".
>
> It's not perfect, but one could grep through /var/run/dmesg.boot looking
> for "cpu" lines and checking for "(AP)" or "(AP/HT)".
>
> --
> Freddie Cash
> fjwcash@gmail.com

I always look at "sysctl kern.sched.topology_spec" to tell if
hyperthreading is enabled.  It's overkill, but it works.  Here's some
Ruby code that can parse it:

require 'rexml/document'

  # Parses the output of "sysctl kern.sched.topology_spec and returns a triple
  # of [number of sockets, cores/socket, threads/core]
  def _parse_topo(topology)
    cpu_xpath = "groups/group/children/group/cpu"
    xmldoc = REXML::Document.new(topology)
    _punt_topo(topology) unless xmldoc.get_elements("groups/group").count == 1
    sockets = xmldoc.get_elements("groups/group/children/group").count
    all_cores_per_socket = Set.new([])
    all_threads_per_core = Set.new([])
    xmldoc.get_elements("groups/group/children/group").each do |group2|
      cores = 0
      children = group2.get_elements("children/group")
      if children.empty?
        # No hyperthreading
        cpu_entities = group2.get_elements("cpu")
        _punt_topo(topology) unless cpu_entities.count == 1
        core_count = cpu_entities.first.attribute("count").value
        cores += core_count.to_i
      else
        children.each do |group3|
          if group3.get_elements("flags/flag[@name='SMT']").empty? && \
             group3.get_elements("flags/flag[@name='HTT']").empty? && \
             group3.get_elements("flags/flag[@name='THREAD']").empty?
          else
            # This cpu group represents a single hyperthreaded core
            cores += 1
            cpu_entities = group3.get_elements("cpu")
            _punt_topo(topology) unless cpu_entities.count == 1
            core_count = cpu_entities.first.attribute("count").value
            all_threads_per_core.add(core_count.to_i)
          end
        end
      end
      all_cores_per_socket.add cores
    end

    if all_cores_per_socket.size > 1
      cores_per_socket = "mixed"
    else
      cores_per_socket = all_cores_per_socket.first.to_i
    end

    if all_threads_per_core.size > 1
      threads_per_core = "mixed"
    elsif all_threads_per_core.size == 0
      # No SMT sections means no hyperthreading
      threads_per_core = 1
    else
      threads_per_core = all_threads_per_core.first.to_i
    end
    [sockets, cores_per_socket, threads_per_core]
  end

    # Helper method for _parse_topo
  def _punt_topo(topo)
    STDERR.puts topology
    raise IOError.new "Output of kern.sched.topology is not understood"
  end

-Alan



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAOtMX2i6MOyHKc08GgyMgsxWcCWUUCTd2qHSnY=9WaZhUm2xdA>