Reputation: 1763
The software I am using support multiple thread and TCL interface. So I am not sure how to find the number of CPUs in TCL to limit the maximum threads.
Upvotes: 2
Views: 2204
Reputation: 815
I tried both the solutions above. @DonalFellows was almost perfect but didn't work on my OSX as the default tclsh was 8.4 and the {*} syntax to exec didn't work. However the {*} construct didn't seem to be required as removing it enabled it to work with tclsh 8.4, 8.5 and 8.6.
I've pasted the code below with that change as I don't have enough reputation to just comment.
proc numberOfCPUs {} {
# Windows puts it in an environment variable
global tcl_platform env
if {$tcl_platform(platform) eq "windows"} {
return $env(NUMBER_OF_PROCESSORS)
}
# Check for sysctl (OSX, BSD)
set sysctl [auto_execok "sysctl"]
if {[llength $sysctl]} {
if {![catch {exec $sysctl -n "hw.ncpu"} cores]} {
return $cores
}
}
# Assume Linux, which has /proc/cpuinfo, but be careful
if {![catch {open "/proc/cpuinfo"} f]} {
set cores [regexp -all -line {^processor\s} [read $f]]
close $f
if {$cores > 0} {
return $cores
}
}
# No idea what the actual number of cores is; exhausted all our options
# Fall back to returning 1; there must be at least that because we're running on it!
return 1
}
Upvotes: 1
Reputation: 1763
The code originally comes from @DonalFellows's answer. But I still get problem with the sysctl
which exists in Ubuntu
but it doesn't have hw.ncpu
.
So I did some changes on it.
proc number_of_processor {} {
global tcl_platform env
switch ${tcl_platform(platform)} {
"windows" {
return $env(NUMBER_OF_PROCESSORS)
}
"unix" {
if {![catch {open "/proc/cpuinfo"} f]} {
set cores [regexp -all -line {^processor\s} [read $f]]
close $f
if {$cores > 0} {
return $cores
}
}
}
"Darwin" {
if {![catch {exec {*}$sysctl -n "hw.ncpu"} cores]} {
return $cores
}
}
default {
puts "Unknown System"
return 1
}
}
}
Tried on Ubuntu
and Windows 7
, it works. I don't have MacOS around me. So that will be good if someone can verify that works or not.
Upvotes: 0
Reputation: 137567
There's nothing built into Tcl; it's been discussed, but not acted on because the number of CPUs is not necessarily the number that the process may use (by far the most relevant reason for having the info). That said, the information is available. It's just that the way you get the information varies by platform.
proc numberOfCPUs {} {
# Windows puts it in an environment variable
global tcl_platform env
if {$tcl_platform(platform) eq "windows"} {
return $env(NUMBER_OF_PROCESSORS)
}
# Check for sysctl (OSX, BSD)
set sysctl [auto_execok "sysctl"]
if {[llength $sysctl]} {
if {![catch {exec {*}$sysctl -n "hw.ncpu"} cores]} {
return $cores
}
}
# Assume Linux, which has /proc/cpuinfo, but be careful
if {![catch {open "/proc/cpuinfo"} f]} {
set cores [regexp -all -line {^processor\s} [read $f]]
close $f
if {$cores > 0} {
return $cores
}
}
# No idea what the actual number of cores is; exhausted all our options
# Fall back to returning 1; there must be at least that because we're running on it!
return 1
}
Note that if you're looking to find out the number of CPUs to run on, what you really want are the number of bits set in the CPU affinity mask. Unfortunately, retrieving that information is non-trivial on most platforms.
Upvotes: 4