Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > Developer Center > Checking number of CPU's

Checking number of CPU's
Thread Tools
Mac Enthusiast
Join Date: Oct 2001
Status: Offline
Reply With Quote
Jul 14, 2002, 06:08 AM
 
I would like to programmatically determine the number of processors a user has on his machine. I know I could do something like:

hostinfo | grep physically | cut -d " " -f1

but this seems 'hackish'

any suggestions?
3R1C
     
3R1C  (op)
Mac Enthusiast
Join Date: Oct 2001
Status: Offline
Reply With Quote
Jul 14, 2002, 06:37 AM
 
Ok. I've found this:

/usr/include/mach/host_info.h

struct host_basic_info {
integer_t max_cpus; /* max number of cpus possible */
integer_t avail_cpus; /* number of cpus now available */
vm_size_t memory_size; /* size of memory in bytes */
cpu_type_t cpu_type; /* cpu type */
cpu_subtype_t cpu_subtype; /* cpu subtype */
};

looking at this header I can tell that it will give me the info I desire, but I'm clueless as to how to get it programmatically. Im guessing that I would import this header:

#import "/usr/include/mach/host_info.h"

but after that how do I ask how many cpu's there are?
would I:

int foo;
foo = host_info(integer_t,avail_cpus);

Is there any source available which does this?
3R1C
     
Mac Elite
Join Date: May 2002
Status: Offline
Reply With Quote
Jul 14, 2002, 07:00 AM
 
I believe what you want is something like this:

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">#import &quot;/usr/include/mach/mach_host.h&quot;

int hostInfoCount, numProcessors;
int hostInfoArray[HOST_BASIC_INFO_COUNT];
host_basic_info_t hostInfo;

hostInfoCount = HOST_BASIC_INFO_COUNT;

if(host_info(mach_host_self() , HOST_BASIC_INFO, hostInfo, &amp;hostInfoCount) == KERN_SUCCESS)
{
hostInfo = (host_basic_info_t) hostInfoArray;
numProcessors = hostInfo.avail_cpus;
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">Having now researched the subject in order to find that out, I'd just like to point out that kernel programming is quite evil.

[Edit: I left off a semicolon. ALWAYS the semicolons, isn't it?]

<small>[ 07-14-2002, 08:03 AM: Message edited by: Gul Banana ]</small>
[vash:~] banana% killall killall
Terminated
     
Mac Enthusiast
Join Date: Nov 2001
Status: Offline
Reply With Quote
Jul 14, 2002, 07:08 AM
 
I thought I'd point out that #import "/usr/include/mach/mach_host.h" can be re-written as #import &lt;mach/mach_host.h&gt;. I suppose it's just better programming style .
     
Mac Elite
Join Date: May 2002
Status: Offline
Reply With Quote
Jul 14, 2002, 07:08 AM
 
I decided to actually test that; after some fiddling, here's something that compiles, runs, and works.

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">#include &lt;stdio.h&gt;
#include &quot;/usr/include/mach/mach_init.h&quot;
#include &quot;/usr/include/mach/mach_host.h&quot;

int main (int argc, const char * argv[]) {
int hostInfoCount, numProcessors;
int hostInfoArray[HOST_BASIC_INFO_COUNT];
host_basic_info_t hostInfo;

hostInfoCount = HOST_BASIC_INFO_COUNT;

if(host_info(mach_host_self() , HOST_BASIC_INFO, hostInfoArray, &amp;hostInfoCount) == KERN_SUCCESS)
{
hostInfo = (host_basic_info_t) hostInfoArray;
numProcessors = hostInfo-&gt;avail_cpus;
printf(&quot;%d&quot;, numProcessors);
exit(0);
}

exit(-1);
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">
[vash:~] banana% killall killall
Terminated
     
Mac Elite
Join Date: May 2002
Status: Offline
Reply With Quote
Jul 14, 2002, 07:10 AM
 
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">quote:</font><hr /><font size="1" face="Geneva, Verdana, Arial, sans-serif">Originally posted by Ibson:
<strong>I thought I'd point out that #import "/usr/include/mach/mach_host.h" can be re-written as #import &lt;mach/mach_host.h&gt;. I suppose it's just better programming style .</strong></font><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">You're perfectly right. Here, then:

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">#include &lt;stdio.h&gt;
#include &lt;mach/mach_init.h&gt;
#include &lt;mach/mach_host.h&gt;

int main (int argc, const char * argv[]) {
int hostInfoCount, numProcessors;
int hostInfoArray[HOST_BASIC_INFO_COUNT];
host_basic_info_t hostInfo;

hostInfoCount = HOST_BASIC_INFO_COUNT;

if(host_info(mach_host_self() , HOST_BASIC_INFO, hostInfoArray, &amp;hostInfoCount) == KERN_SUCCESS)
{
hostInfo = (host_basic_info_t) hostInfoArray;
numProcessors = hostInfo-&gt;avail_cpus;
printf(&quot;%d&quot;, numProcessors);
exit(0);
}

exit(-1);
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">
[vash:~] banana% killall killall
Terminated
     
3R1C  (op)
Mac Enthusiast
Join Date: Oct 2001
Status: Offline
Reply With Quote
Jul 14, 2002, 07:18 AM
 
Evil is right. Im a fledgling cocoa dev at best, and I must admit that the supplied code means little to me. I however thank you. I get two warnings and an error on compile.

warning: implicit declaration of function `mach_host_self'
warning: passing arg 3 of `host_info' from incompatible pointer type
request for member `avail_cpus' in something not a structure or union

Im sure that Im missing something obvious (to everyone but me)

questions:

shouid these be in my .h or my .m?

int hostInfoCount, numProcessors;
int hostInfoArray[HOST_BASIC_INFO_COUNT];

I put everything in my .m

where should I put what? Thanx alot Gul
3R1C
     
3R1C  (op)
Mac Enthusiast
Join Date: Oct 2001
Status: Offline
Reply With Quote
Jul 14, 2002, 07:34 AM
 
Man you guys are fast! before I could even prepare my question you had answers.

The app Im working on is a prefpane. So the project that was created doesnt have a main.m which is always created when I make an app.

this line from your supplied code:

int main (int argc, const char * argv[])

looks to be that line I always see in the main.m
I have no idea what the main.m is for

Should I make a main.m and put your code in there?
3R1C
     
Mac Elite
Join Date: May 2002
Status: Offline
Reply With Quote
Jul 14, 2002, 07:41 AM
 
I'll Objective-Cify that code for you, making it into a method of an object.

In the header of the object file (the .m file such as Thing.m), put
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">#include &lt;mach/mach_init.h&gt;
#include &lt;mach/mach_host.h&gt;</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">Now, give the object the following method:

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">+ (int)numberOfProcessors
{
int hostInfoCount;
int hostInfoArray[HOST_BASIC_INFO_COUNT];
host_basic_info_t hostInfo;

hostInfoCount = HOST_BASIC_INFO_COUNT;

if(host_info(mach_host_self() , HOST_BASIC_INFO, hostInfoArray, &amp;hostInfoCount) == KERN_SUCCESS)
{
hostInfo = (host_basic_info_t) hostInfoArray;
return (hostInfo-&amp;gt;avail_cpus);
}

return 0;
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">Let's say the class was called NSThing; [NSThing numberOfProcessors] would return the number of available processors or, if an error occurred, 0.

[Edit: adding more information]
As to what </font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">int main (int argc, const char * argv[])</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">means:
The main function of a program is the one that is called when it runs. In Cocoa applications, this function generally calls NSApplicationMain(), which starts the main run loop. My original code was for a command-line application, in which argc is the number of arguments given and argv is the array of strings containing them (the arguments). To compile that, you would put it in a file such as "cpunum.c" and type "gcc -o cpunum cpunum.c".

If, by the way, you don't understand the stuff before the Edit (how to make a new class and give it a method) I'd recommend you read some more about Cocoa before trying to make a prefpane.

<small>[ 07-14-2002, 08:45 AM: Message edited by: Gul Banana ]</small>
[vash:~] banana% killall killall
Terminated
     
3R1C  (op)
Mac Enthusiast
Join Date: Oct 2001
Status: Offline
Reply With Quote
Jul 14, 2002, 08:00 AM
 
Sir: Your skills are potent.

I believe it is working properly, as I have a duallie and it returns 2
I just need a buddy with 1 proc to test my prefpane and I'm golden.

Although I am positive this goes without saying I add the following for others who will read this thread.

This also must go in the .h

+ (int)numberOfProcessors;

thanx again for your tutelage. If a moron like me can get this stuff to work, anyone can dev. =)
3R1C
     
Mac Elite
Join Date: May 2002
Status: Offline
Reply With Quote
Jul 14, 2002, 08:11 AM
 
I'm glad I was able to be of help! The code returns 1 for me, by the way, which is indeed the number of processors I have, though obviously the more testing the better.
[vash:~] banana% killall killall
Terminated
     
Junior Member
Join Date: Jul 2001
Location: Mos Eisley Cantina
Status: Offline
Reply With Quote
Jul 14, 2002, 07:21 PM
 
You can also use the Multiprocessing Services API (in CoreServices) MPProcessors(). Eg:

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">#import &lt;CoreServices/CoreServices.h&gt;

int main(void)
{
printf(&quot;Num procs is %d\n&quot;, MPProcessors());
return 0;
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">A quick test on my PowerBook shows that this returns 1 CPU. I don't have a dual processor machine to test this with, though.

<small>[ 07-14-2002, 08:25 PM: Message edited by: PipelineStall ]</small>
     
Mac Elite
Join Date: Sep 2000
Location: in front of the keyboard
Status: Offline
Reply With Quote
Jul 14, 2002, 07:46 PM
 
</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">quote:</font><hr /><font size="1" face="Geneva, Verdana, Arial, sans-serif">Originally posted by PipelineStall:
<strong>You can also use the Multiprocessing Services API (in CoreServices) MPProcessors(). Eg:

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">#import &lt;CoreServices/CoreServices.h&gt;

int main(void)
{
printf(&quot;Num procs is %d\n&quot;, MPProcessors());
return 0;
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">A quick test on my PowerBook shows that this returns 1 CPU. I don't have a dual processor machine to test this with, though.</strong></font><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">Seems to work....

Num procs is 2

NumCpu has exited with status 0.

On my Dual 800
signatures are a waste of bandwidth
especially ones with political tripe in them.
     
Mac Elite
Join Date: May 2002
Status: Offline
Reply With Quote
Jul 15, 2002, 12:07 AM
 
Geh, that's much easier! Oh well, I learnt more the other way.
[vash:~] banana% killall killall
Terminated
     
Dedicated MacNNer
Join Date: May 2001
Status: Offline
Reply With Quote
Jul 19, 2002, 12:47 AM
 
Hey all--

I'm just learning cocoa as well (and object oriented programming in general), and here's a pretty easy question I'm sure.. But I'm trying to figure when to make a method an instance method vs. a class method (the Apple docs are pretty oblique).

In this case:

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">+ (int)numberOfProcessors
{
int hostInfoCount;
int hostInfoArray[HOST_BASIC_INFO_COUNT];
host_basic_info_t hostInfo;

hostInfoCount = HOST_BASIC_INFO_COUNT;

if(host_info(mach_host_self() , HOST_BASIC_INFO, hostInfoArray, &amp;hostInfoCount) == KERN_SUCCESS)
{
hostInfo = (host_basic_info_t) hostInfoArray;
return (hostInfo-&amp;gt;avail_cpus);
}

return 0;
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">I presume it's made an class method (+) because the result is the same regardless of a particular instance of this class? (Ie, you don't even need one.) Is there a general "rule of thumb" one uses for deciding whether to use a + or -?

Sorry, I'm sure this is pretty elementary. From browsing the various classes, I'm kind of gleaning that a class method doesn't rely on any particular instance of the class existing, which I guess would apply here. Is that basically the deal? Or am I totally confused?

Thanks. I'm gonna use the above code in something I'm working on, if that's cool... <img border="0" title="" alt="[Wink]" src="wink.gif" />
W
     
Mac Elite
Join Date: May 2002
Status: Offline
Reply With Quote
Jul 20, 2002, 05:28 AM
 
You're basically right about the reason I chose to make it a class method. You could have, then, an abstract class - say, HardwareReporter - with a number of similar methods, and just call them whenever you needed the information, without having to instantiate anything. There's no problem with calling a class method on something that _does_ have instances, so it was a case of this-might-make-things-better-and-won't-make-them-worse. Feel free to use the code; I relinquish any rights to it whatsoever. PipelineStall's way of doing it might be better, actually.. less efficient, but more high level. (Is that a tautology?)
[vash:~] banana% killall killall
Terminated
     
Dedicated MacNNer
Join Date: Jan 2001
Location: Virginia, US
Status: Offline
Reply With Quote
Jul 21, 2002, 01:00 PM
 
Just for completeness, here's how you get the value using sysctl(). This way is a little bit more portable than the others.

</font><blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">code:</font><hr /><pre style="font-size:x-small; font-family: monospace;">#include &lt;sys/sysctl.h&gt;

int NumProcessorsSysctl()
{
int mib[2];
int numprocs = 0;
size_t len = sizeof(numprocs);

mib[0] = CTL_HW;
mib[1] = HW_NCPU;
sysctl(mib, 2, &amp;numprocs, &amp;len, NULL, 0);
return numprocs;
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">
     
   
Thread Tools
Forum Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Top
Privacy Policy
All times are GMT -5. The time now is 10:03 PM.
All contents of these forums © 1995-2011 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.7 © 2000-2011, Jelsoft Enterprises Ltd., Content Relevant URLs by vBSEO 3.3.2