objc_release taking significant cpu time in profile
wtholliday opened this issue · comments
Based on examining generated assembly, I think the solution may be to use methods on MNVGcontext
to access the instance variables directly. For example:
-(void) convexFill:(MNVGcall*)call {
const int kIndexBufferOffset = call->indexOffset * _indexSize;
[self setUniforms:call->uniformOffset image: call->image];
[_renderEncoder setRenderPipelineState:_pipelineState];
if (call->indexCount > 0) {
[_renderEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle
indexCount:call->indexCount
indexType:MTLIndexTypeUInt32
indexBuffer:_buffers.indexBuffer
indexBufferOffset:kIndexBufferOffset];
}
// Draw fringes
if (call->strokeCount > 0) {
[_renderEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip
vertexStart:call->strokeOffset
vertexCount:call->strokeCount];
}
}
and then
static void mtlnvg__convexFill(MNVGcontext* mtl, MNVGcall* call) {
[mtl convexFill: call];
}
This seems to work. I made the change to convexFill
and it no longer appears on the profile.
@wtholliday Thanks. I created a new branch and moved MNVGcontext-related implementation to the Objective C part. Can you try if it works for you? It would be nice if you can take another profiling screenshot for the changes. https://github.com/ollix/MetalNanoVG/tree/objc
@olliwang that was fast! :)
It's improved, but I'm still seeing a bit of retain/release:
It's still accessing properties of MNVGbuffers
. Is there a clean way to avoid that?
Actually, you can declare an ivar @public
. I didn't know that.
So perhaps a cleaner solution to all of this is to use public ivars, which would avoid the objc_msgSend
I'm seeing creep into the profile (2.5%):
@wtholliday I'm not sure if it works. Try the latest commit. 68fe3b2
@olliwang There are still properties on MNVGbuffers
. I tried making one into a public ivar and it seemed to help.
I would make all the properties on MNVGcontext
into public ivars and get rid of the methods I suggested earlier.
No retain/release, and no msg_send
.
Getting there :)
@wtholliday All rest properties are strong references. Wouldn't that be a problem in ARC?
@olliwang I think the public ivars will work fine in terms of ARC.
I converted one of the properties over to a public ivar, and I saw a call to objc_storeStrong
in the assembly when assigning the ivar.
@wtholliday Is the strong object released properly when assigning a new object to the same public ivar?
@olliwang I assume objc_storeStrong
does that.
I converted commandBuffer
(created per frame) over to a public ivar and I don't see any leaks in the memory graph debugger or in the leaks instrument.
@wtholliday Thanks. I just updated the branch. Please check if the latest commit works.