 |
 |
Checking number of CPU's
|
 |
|
 |
|
Mac Enthusiast
Join Date: Oct 2001
Status:
Offline
|
|
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
|
| |
|
|
|
 |
|
 |
|
Mac Enthusiast
Join Date: Oct 2001
Status:
Offline
|
|
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
|
|
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 "/usr/include/mach/mach_host.h"
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, &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
|
|
I thought I'd point out that #import "/usr/include/mach/mach_host.h" can be re-written as #import <mach/mach_host.h>. I suppose it's just better programming style  .
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Elite
Join Date: May 2002
Status:
Offline
|
|
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 <stdio.h>
#include "/usr/include/mach/mach_init.h"
#include "/usr/include/mach/mach_host.h"
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, &hostInfoCount) == KERN_SUCCESS)
{
hostInfo = (host_basic_info_t) hostInfoArray;
numProcessors = hostInfo->avail_cpus;
printf("%d", 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
|
|
</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 <mach/mach_host.h>. 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 <stdio.h>
#include <mach/mach_init.h>
#include <mach/mach_host.h>
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, &hostInfoCount) == KERN_SUCCESS)
{
hostInfo = (host_basic_info_t) hostInfoArray;
numProcessors = hostInfo->avail_cpus;
printf("%d", numProcessors);
exit(0);
}
exit(-1);
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">
|
|
[vash:~] banana% killall killall
Terminated
|
| |
|
|
|
 |
|
 |
|
Mac Enthusiast
Join Date: Oct 2001
Status:
Offline
|
|
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
|
| |
|
|
|
 |
|
 |
|
Mac Enthusiast
Join Date: Oct 2001
Status:
Offline
|
|
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
|
|
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 <mach/mach_init.h>
#include <mach/mach_host.h></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, &hostInfoCount) == KERN_SUCCESS)
{
hostInfo = (host_basic_info_t) hostInfoArray;
return (hostInfo-&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
|
| |
|
|
|
 |
|
 |
|
Mac Enthusiast
Join Date: Oct 2001
Status:
Offline
|
|
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
|
|
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
|
|
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 <CoreServices/CoreServices.h>
int main(void)
{
printf("Num procs is %d\n", 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
|
|
</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 <CoreServices/CoreServices.h>
int main(void)
{
printf("Num procs is %d\n", 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
|
|
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
|
|
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, &hostInfoCount) == KERN_SUCCESS)
{
hostInfo = (host_basic_info_t) hostInfoArray;
return (hostInfo-&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
|
|
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
|
|
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 <sys/sysctl.h>
int NumProcessorsSysctl()
{
int mib[2];
int numprocs = 0;
size_t len = sizeof(numprocs);
mib[0] = CTL_HW;
mib[1] = HW_NCPU;
sysctl(mib, 2, &numprocs, &len, NULL, 0);
return numprocs;
}</pre><hr /></blockquote><font size="1" face="Geneva, Verdana, Arial, sans-serif">
|
|
|
| |
|
|
|
 |
 |
|
 |
|
|
|
|
|

|
|
 |
Forum Rules
|
 |
 |
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is Off
|
|
|
|
|
|
 |
 |
 |
 |
|
 |
|