BMesh: Optimize copying attributes from many elements at once #115824
No reviewers
Labels
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: blender/blender#115824
Loading…
Reference in New Issue
No description provided.
Delete Branch "HooglyBoogly/blender:bmesh-cd-copy-performance-fix"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Fixes #115776
Create a minimal structure that contains the instructions necessary to
copy from one custom data format to another. This structure is similar
to the one used in
dfacaf4f40
. It should have been used in9175d9b7c2
, which instead introduced quadratic performancerelative to the number of layers when copying every element.
In this commit, copying the entire mesh and adding new custom data
are explicitly changed to use the new map to speed up copying many
elements at a time.
The non-map attribute copy functions are also changed to check for when
the source and result BMeshes are the same. In that case it's much
faster to call the "same format" function from
9175d9b7c2
.For numbers, the timings are arbitrarily influenced by how many layers
I add in my testing. With 50 or so layers, a 10x difference is easily
observable though.
Generally fine, only request is not to expand existing cases where a single function call ends up in-lining normal/material copying. While there aren't many cases I think it's reasonable we keep something like
BM_elem_attrs_copy_ex
so Python logic doesn't have to inline this.If we want to make using a map the more obvious choice we could even remove
_with_map
functions and have_without_map(..)
/_no_map(..)
with warnings that these functions should be avoided if at all possible.@ -360,0 +391,4 @@
const CustomData &dst,
eCustomDataMask mask_exclude = 0);
void CustomData_bmesh_copy_block_with_map(const BMCustomDataCopyMap &map,
Prefer to order the helper argument (map in this case) last, since it's the convention to have containers first
bm
in this case.@ -1498,0 +1503,4 @@
BMVert *dst = reinterpret_cast<BMVert *>(self->ele);
CustomData_bmesh_copy_block(
&value->bm->vdata, &self->bm->vdata, src->head.data, &dst->head.data);
copy_v3_v3(dst->no, src->no);
Prefer use a utility function for each type instead of copying each type & it's members here.
Not sure that's necessary for now. I think there's still room to make copying without a prebuilt map faster. So maybe it won't be that necessary long term, though it will always be worth it for things like reallocating all custom data blocks. I'd almost prefer to just use one overloaded name for that. But I left it as is now.
_with_map()
version should note in doc-string thewith_map()
version should be preferred when calling multiple times.Doesn't require an extra iteration, accepting.
Good idea.
I don't agree with that as a general rule, but I don't care much in this case, so I'll change it so we can move on.
Actually I do care here :P The reason to have it not last is all of the constant/global arguments come before the arguments that change for every copy/iteration. I think that's a much better general rule ("global/larger scope arguments first") than "caches last". Are you okay with that?
It's not that cache should have a particular argument location, it's that this is extra/optional information
(optional in the sense there is a function which doesn't require it, and this is an extended version of that function).
Reads more logically to me than:
I don't think that logic scales. To me, the existence of a different version of a function with different arguments doesn't mean those arguments should go last. They should go in the logical order in the context of that version of the function. And we already have a fairly well established ordering for that sort of "global" vs. "per iteration" data.
This is the current convention for
_ex()
although that means (extended), we don't have such clear conventions for_with_*(..)
suffix functions, but it reads strangely to me to re-order arguments.Reading over the patch there are two functions called
CustomData_bmesh_copy_block(..)
one that takes a single mesh which doesn't need a mapping, and another that calculates and passes a map toCustomData_bmesh_copy_block_with_map(..)
.The problem with this is one of these functions we should really avoid where possible but it's got the same name as a function that doesn't have a performance problem. Checking over the code it's used ~17 or so places, many of these cases map can be calculated and reused.
Suggestion:
CustomData_bmesh_copy_block_with_map(..)
toCustomData_bmesh_copy_block
.CustomData_bmesh_copy_block
that generates it's a map to_without_map(..)
,_no_map(..)
or similar.This means callers are aware there is a map that should be reused, and using a map is the default.
Note, we could even remove the non-map version of the function however it's used enough right now that it's not so convenient at the moment.
I removed the non "with map" version for copying between two different
CustomData
formats and removed the "with map" suffix. I think this state is fine now, should make both of us happy :)Much better although I´m still uneasy that a 100x slower function is named in a way that doesn´t make this down-side explicit, longer term it might be good to phase out the slow version entirely.
Was stumbling over this, shouldnt it be the following?
Thanks, resolved in
fb5d03b5ba