When executing compute shaders you just dispatch a grid of tasks. Whether this grid elements match each pixel of your texture is up to you. So indeed your guess about dispatching a grid of the size of the region of the source texture and adding an offset (the origin of the region) to the gid to know which pixel coordinate to read is correct.
Post
Replies
Boosts
Views
Activity
Blind guess but maybe missing a const in
device MyParams& params [[ buffer (0) ]]
?
I suppose you’re affected by https://developer.apple.com/documentation/metal/preparing_your_metal_app_to_run_in_the_background
I don't know if you're seeing a leak in RAM or VRAM. In both cases, Instruments can help you identify its source: with the Allocations instrument template if it's a RAM leak, or with Metal System Trace instrument template if it's a VRAM leak (in Metal Resource Events).
It depends on the complexity of the model you want to run or train. If you're only doing light work, any Mac will do. If your model is heavy or processing a lot of data, then AMD GPUs (or soon Neural Engine) are significantly more efficient, so in that case avoid Macs with only Intel graphics.
In your simplified example, did adding an autorelease pool fixed it? Just to know if it's the culprit.
Did you check https://developer.apple.com/documentation/metal/synchronization/synchronizing_events_between_a_gpu_and_the_cpu ?
We only know about announced OS. So you know that you're ok at least until iOS 15/macOS 12 are released Fall 2021. And you'll know about these next June.
Did you check https://developer.apple.com/documentation/metal/calculating_threadgroup_and_grid_sizes ?
Especially the part with
« You calculate the number of threads per threadgroup based on two MTLComputePipelineState properties. One property is maxTotalThreadsPerThreadgroup (the maximum number of threads that can be in a single threadgroup). The other is threadExecutionWidth (the number of threads scheduled to execute in parallel on the GPU). »
Looks like these properties would help.
How did you dispatch the work in host code?
Especially regarding the threads per threadgroup. You may want to check https://developer.apple.com/documentation/metal/calculating_threadgroup_and_grid_sizes
This can make a big difference in efficiency.
Apart from that, as Etresoft already mentionned, you should check the performance data provided by GPU Frame Capture.
https://developer.apple.com/documentation/metal/mtlbuffer/1515373-length
https://developer.apple.com/documentation/metal/mtlresource/2915287-allocatedsize
I'd say what matters is the allocated size, and I suppose that it could be bigger that the requested length to satisfy alignment constraints.
I ran into the same issue. And at least for the purpose of getting the view size, I'm relying on a parent GeometryReader instead, see https://github.com/Ceylo/FurAffinityApp/blob/main/FurAffinity/Helper%20Views/TextView.swift#L37
You can use Metal System Trace template in Instruments to check if there's any activity on GPU from your process or any other application. Then you can confirm whether lost GPU power comes from your compute kernels or not.
For profiling of your GPU pipeline, you have Metal System Trace in Instruments: https://developer.apple.com/documentation/metal/performance_tuning/using_metal_system_trace_in_instruments_to_profile_your_app
For profiling of the shaders themselves, along with metrics about what is limiting their speed, you'll want to use GPU frame capture in Xcode: https://developer.apple.com/documentation/metal/debugging_tools
Note that GPU frame capture can be triggered manually from Xcode when you have frames displayed, but in your case you can also use MTLCaptureManager in your code to start & stop this capture around your compute workload. So no need to have a graphic pipeline to use these tools.
I'm not sure everything will help, and I don't know for the WebKit offscreen rendering, but here are at least three points I can mention:
Don't take iPhone simulator as a reference for your benchmark, use a real device
Being on iPhone you can take advantage of the unified memory architecture and create textures without doing any copy, if the source data is properly allocated and aligned. In particular see https://developer.apple.com/documentation/metal/mtldevice/1433382-makebuffer and https://developer.apple.com/documentation/metal/mtlbuffer/1613852-maketexture. This means that the CGImage buffers in which you render to must have been allocated by you, following above constraints, and that the CGImage must only wrap your pointers, not copy your data to its own buffers (I'm not sure if CGImage can do that, so you might need to render into something else than a CGImage).
If the size of the texture doesn't change, you can reuse the texture but make sure it's not used by Metal while you write to it: either you wait for MTLCommandBuffer to complete, or you create several buffers/textures that you reuse over time to account for triple buffering of your rendering.