precompiler test for cpu count

I use as many cpu's as I can get with DispatchQueue. How do I test the Mac for cpu count in my code?

Replies

I have attempted to use sysctl() to retrieve the count. It prints the correct value to standard out, i.e., the debugger area but Idk how to capture it in swiftui. ".standardOutput" throws something called an "NSConcreteTask", and not the Int() I was expecting. NSConcreteTask has no entry in the "Developer Documentation" of Xcode, so I'm stuck.

    let getCPUct = Process()
    getCPUct.executableURL = URL(fileURLWithPath: "/usr/sbin/sysctl")
    getCPUct.arguments     = ["-n", "hw.ncpu" ]
    do {
        try getCPUct.run()                                          //  throws 6 to standard out
        if let output      = getCPUct.standardOutput as? Int {
            print("#file:#line cpu count = \(output)")
            return output
        }
    }
    catch let error as NSError { print("Failed to execute sysctl", error) }
    return 0
}

Re-discovered eskimo's "//developer.apple.com/forums/thread/690310". Result:

launch(tool: URL(fileURLWithPath: "/usr/sbin/sysctl"), arguments: ["-n", "hw.ncpu" ], completionHandler: { (status, outputData) in
                                    let output = String(data: outputData, encoding: .utf8) ?? ""
                                    self.ncpu = (output as NSString).integerValue
                                   print("done, status: \(status), output: \(self.ncpu)")
                                })

where I had declared ncpu elsewhere in the app.

Thank you eskimo!

Running the sysctl command-line tool to get this info is extremely costly. You can get the same info by calling the sysctlbyname function. See its man page for details.

Having said that, scaling work based on the number of CPUs is not always a good choice. What do you plan to do with that info?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

  • FYI: "man sysctlbyname" does deliver a man page but "which sysctlbyname" gives: "sysctlbyname not found". Also, mdfind sysctlbyname is void.

Add a Comment

My original intent was flawed, i. e., trying to optimize code using pre-compiler tests would only be useful for those who would be compiling, and not app users.

What do you plan to do with that info?

My app has nested for-loops sometimes eighteen deep. By strategically placing DispatchQueue's between the outer loops I can keep all my cpu's busy, minimizing compute time. In an app I can Switch() on the ncpu to the appropriate nest for optimization. As one who compiles the code, it's actually easier for me to edit the nests to my machines ncpu. A second flaw in my thought process is that once the data is generated no-one need generate it again. Nevertheless, I love solving mysteries or maybe just pursuing solutions.

man sysctlbyname does deliver a man page but which sysctlbyname gives

Right. sysctlbyname is an API, not a command-line tool (the equivalent command-line tool is sysctl). If you want to get the core count, do that by calling the API rather than invoking the command-line tool.

By strategically placing DispatchQueue's between the outer loops I can keep all my cpu's busy, minimizing compute time.

Is this work entirely CPU bound?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Is this work entirely CPU bound?

No GPU's involved, so I guess so. The app does nothing outside of the machine upon which it runs. Once the database is generated the app just becomes a viewing instrument. This reply is two weeks late because for two weeks the machine was busy generating useless data. lol. (Down from a 300 year estimated compute time, so yay, progress!)

We can probably close this thread because I have no need to generate data on unknown machines. Thanks.