-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactored Bucket class #1645
Refactored Bucket class #1645
Conversation
if (isNaN(joinNormal.x) || isNaN(joinNormal.y)) { | ||
return; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where did this come from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops! Just some innocuous-looking leftover debugging code. Will remove in the next commit.
dd4af12
to
916b75a
Compare
body += ' attributes[' + k + '].value(' + argIds.join(', ') + ')'; | ||
body += (k !== shader.attributes.length - 1) ? ',\n' : ''; | ||
} | ||
body += '\n) - elementGroups.current.vertexStartIndex;'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might have better luck with separate push
calls for each separate value. There's was a severe performance regression on it in V8 that I reported https://code.google.com/p/v8/issues/detail?id=3883
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, nevermind, this is buffer push.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might have better luck with separate push calls for each separate value
I benchmarked this last week anyway and was surprised to see little performance improvement. Looks like trading array allocations for stack allocations is a wash.
This PR generally looks good, but I have the same concerns as in the previous PR — value functions and temporary array for each vertex. The general issue here is that I don't yet see the big picture of how we'll use that later with disablable/updatable attributes, so I can't come up with a better way since it might interfere with your vision of data-driven style implementation. Could we cut out this specific change and add it in a different PR that actually makes use of the change (like a disabled attribute)? |
I'm open to that. I'll back out those changes this morning. |
On further thought, I don't think this PR makes much sense with the removal of value functions (or some equivalent structure). I have an 😈 idea that might win us the performance gains we need while keeping the flexibility of this approach. |
Don't know if this is too 😈 but it actually results in somewhat simpler code. Interestingly, it does not seem to confer a big performance benefit.
|
Interesting clue: |
Looks like eliminating 1 property lookup from |
@lucaswoj you might have bumped under 600 characters limit for V8 function inlining which could cause the perf increase. |
It doesn't make much sense with them as well because it's still not clear how to move this forward without a clear use for the separate attribute value calculations. Without the code actually making use of the change, it's not clear how I could change it to match previous performance, and obviously we can't merge something that makes tile loading 2-3 times slower without a good reason. To unstall the PR, you'll have to either add the code that justifies the value functions change (e.g. some basic form of disablable attributes), or at least give a detailed description of how exactly the disabling will work with this code. |
With the latest commit, this branch is nearly as fast as master!
(who knew it would be so easy)
I want to decouple the 1:1 relationship between shader attributes and buffer attributes -- that the attributes of one buffer layout are exactly the attributes of one shader type. For data-driven styling to work, we are going to want a single shader to use global attributes and potentially attributes from multiple buffers. This PR makes it possible to calculate the values of attributes independently, making it easy & efficient to send attribute values to different places and recalculate them independently. We don't use that capability yet but there is no "dead" code in this PR. |
df4df04
to
3b295a1
Compare
Just checked the following browsers for perf regressions (and found none)
|
@mourner with these performance improvements and my description of why we need to separate the logic used to calculate each attribute, are you willing to consider merging this into There are still a few dependencies we need to actually leverage disable-able attributes (items 3, 4, 5, and 6 in #1626). |
Things I've tried to further close the performance gap, to no avail
|
@lucaswoj yes, I think this is pretty close to being merged. But it would great for @jfirebaugh to review this as well — big important PRs like this need more than one pair of 👀 |
|
||
this.resetBuffers(options.buffers); | ||
|
||
this.add = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this used anywhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope. Deleted in the next commit.
I'm not clear on why we're introducing knowledge of shaders into this code. There's a loop in |
We are moving towards a paradigm in which a shader's attributes may span several
Yes, there is an assumption that we don't introduce conflicting shader definitions. This problem will go away when we start supporting "disable-able attributes" and I will add an assertion that each shader is only defined once.
The interface of the shader is fixed. The way we fulfill that interface will be decided by the |
Okay, let me know if the following understanding is correct: The current implementation statically groups attributes into buffers based on their use in shaders. The influence of shaders on the existing code is thus implicit. This PR makes the influence explicit. However, we want to be moving towards a model where the grouping of attributes into buckets is dynamically determined. If that's correct, I would argue that making "shader" into an explicit domain concept in this part of the code is actually counterproductive to your goal. It sounds like a better domain model would be "attributes" and "attribute groups". For now, the attribute groups would be statically defined and (implicitly) correspond to shaders, but we'd have a domain model that wouldn't need to be reworked again for dynamic attribute grouping. |
Even when we have dynamic attribute grouping, we still need knowledge about the shader's attributes. The union of all dynamic attribute groups must equal the shader's attributes. |
So, for example, the |
Also worth noting: my long-term vision is to merge this class, the |
Let me try to approach this from a more concrete angle. We definitely envision a scenario where a single shader pulls data from multiple buffers. Do we envision a scenario where a single buffer supplies data to multiple shaders?
|
I believe the answer to this question is "no." If the shaders are different, the feature geometries are different and there is no meaningful way to share buffers.
I think we still want to deduplicate these buffers. If there are 10 Alternately, we could have another entity responsible for creating all the buffers up front. This is not desirable once we start introducing dynamic attribute grouping, however. |
👍 The loop I'm referring to is this one, and the deduplication is the conditions like |
|
Ah, I see. Does that possibility exist only because we haven't fixed #1585 yet? |
Yes, #1585 would make this check unnecessary. |
Great. Sorry for jumping to conclusions about why that was there. 🚢! |
No worries John! I really appreciate your thoroughness. I think I'm seeing a small perf regression in the latest commit -- maybe because of inlining limits? I'm going to give it a look on Monday before pulling the trigger. On Fri, Oct 30, 2015 at 3:47 PM, John Firebaugh notifications@github.com
|
elementGroups
always an object of multiple instances ofElementGroups
createBucket
module in favor of a simpleBucket.create
method and a smarter constructor