Thanks for the clarification that this affects indeed all devices with Apple SoCs (both on iOS and Mac). And yes, the comparison was against an Intel Mac where I don't encounter any measurable CPU load at all with Metal.
My primary concern is that this current, inevitable base CPU load linearly accumulates with every Metal widget, which I just tried and it apparently does; the CPU load increase is almost linear (e.g. with 8 noop Metal widgets, CPU load increases by factor ~7.5). Sometimes I even see a full saturation of all CPU cores steadily for several minutes for some reason. I did not have a chance to try with an Apple M1 Mac yet, but looking at its specs I would assume a similar performance result there.
So if I understand it correctly, the current design of Metal + Apple GPU is rather dedicated to single Metal widget applications like games that commonly only have one full screen Metal widget. In standard applications though it is more common to primarily use stock widgets (e.g. from UIKit or Cocoa on iOS/Mac) and adding multiple, custom GPU accelerated widgets (Metal, OpenGL/CL) where necessary.
Am I correct that the situation is the same with OpenGL/CL on Apple SoCs? Or is this something specific to Metal only?
What I'm also wondering is why this issue does not affect stock widgets at all. I mean UIKit widgets are also running on top of Metal, aren't they?
Post
Replies
Boosts
Views
Activity
I filed a bug report (FB8919375).
If anybody could confirm or deny this behaviour on (real) iOS devices, very much appreciated.
Same error here when launching iOS simulator with Xcode 12.2. Cleaning the build dir does not solve it though.
I filed a bug report on Nov 25th, no reaction so far (FB8916777).
Any other known workaround?
mattke is right, the comparison is unfair as the OpenCL code uses vectors, while the Metal code just uses a scalar type. You have a bunch of options to fix that. You can either use a loop over 8 scalars in your Metal kernel function which the Metal compiler will unloop (i.e. vectorize) for you automatically, and/or you can use SIMD code. You also need to adjust the thread grid after those changes.
Some other things that come to my mind (some of them were already suggested): Enable fast-math for the Metal compiler to prevent a massive slow down if the GPU encounters denormals.
For the input buffers you probably want to use constant as address space specifier instead of device. (i.e. device const is not the same as constant const).
Use & instead of * for function arguments where possible.
It's not clear to me what your actual question is. If you want to see the buffer index in the frame capture debugger, you can simply assign a struct with an uint variable as a buffer to your shaders, set the current buffer index to that buffer in your display function and then you see the value when you debug your shader functions(s) in a frame.
Works here with macOS 10.15.7, Xcode 12.2 and iOS 14.2.
What's your deployment target there? I think I had to raise it to iOS 12.0 for frame capturing to work with (real) iOS devices. Frame capturing is grayed out on iOS simulator here, but I guess that's simply not supported on the simulator, for whatever reason.
Agreeing on most what MoreLightning said, plus another major aspect here is that Swift cannot cope with C + + code at all. There is a reason why Apple chose C+ + as basis for their Metal language, not Swift. In high performance and/or real-time sensitive software, companies usually have a fairly high amount of code portion written in a system level language, typically C or C + +. Application level languages like Swift, Objective-C or Java don't fulfil the requirements for that. So application level languages (Swift, Objective-C, Java, ...) are usually only used in such applications to handle some of the UI API calls with the system, and accordingly they must somehow be capable to interface with the other code portions of the application written in a system level language like e.g. C or C + +.
Objective-C code can be mixed with both C and C+ + code (for the latter you just have to rename the .m file to .mm in Xcode or select "Objective-C + + Source" from the file inspector on the right side). Swift source code however can only be mixed with C code. So if you really wanted to use Swift for the iOS/macOS API handling, then in practice you would need to manually write a huge amount of C bindings for your app's C + + code portions. Not bored^TM.
BTW what's the deal with the forum these days, that it's now interpreting C + + (without spaces) as underline markup? @Apple: please fix this!
I would recommend you getting used to having several Xcode versions installed in parallel by downloading and installing the manually instead of using the Mac App Store solution. You will often find yourself in a situation where you might want to use some Xcode version over the other for various reasons. Many developers are doing this for years and it is fortunately straight-forward:
Login to developer.apple.com
Navigate to Account -> Downloads -> More
Download the Xcode version(s) you need (maybe even some ancient ones).
After download completed click on the .xip file to uncompress it.
Rename the app bundle(s) so you can distinguish them by version (e.g. "Xcode.app" -> "Xcode12.2rc.app").
Move the renamed Xcode app bundle(s) To Applications.
That way you can launch whatever Xcode version you need at any time.
In some rare cases you might want to run an older Xcode version with an iOS device running a bleeding edge iOS version officially not supported by the older Xcode version. In this case you can often just copy the respective directories from Xcodewhatever.app/Contents/Developer/Platforms/iPhoneOS/DeviceSupport/ over to your older Xcode version's app bundle.