Hi Laurent,
A tip on webrevs, if you supply a file of filenames then you can tell it
to diff a file with a name change against its former name by using 2
filenames on the same line, as in:
--------
filetodiff1.java
filetodiff2.java
filetodiff3.java filetodiff3oldname.java
filetodiff4.java
--------
In Renderer.java, you create the alphaLine and blkFlags refs as Clean,
but then you always put them back using indices of (0, 0) so they will
never actually be cleaned - is there a reason you don't just use a dirty
ref there?
Other than that question, I don't see any problems with the fix...
...jim
On 08/01/2016 02:17 PM, Laurent Bourgès wrote:
Hi Jim,
Here is an updated webrev:
http://cr.openjdk.java.net/~lbourges/marlin/marlin-8159638.1/
Changes:
- merge Clean/Dirty Xxx ArrayCache using the flag 'clean' to indicate if
the cache is clean or dirty + the putArray method always performs the
array cleanup
- ArrayCache renamed to ArrayCacheConst + simplified thresholds
More comments, below:
2016-07-21 23:41 GMT+02:00 Jim Graham <james.gra...@oracle.com
<mailto:james.gra...@oracle.com>>:
On 07/21/2016 06:56 AM, Laurent Bourgès wrote:
I don't have any issues with those numbers, but the way that
they
are calculated makes it look like they are supposed to be unique
numbers and yet through the obscurity of the loops used to
populate
the sizes they just end up all being the same numbers - it
makes me
wonder if there was a mistake in there or not...?
Initially these values have different values / meanings but it
can be
simplified now.
To be clear, I wasn't complaining about the multitude of thresholds,
but rather that the way they were apportioned - sort of as a side
effect of the computations in a loop - ended up accidentally
squashing a couple of them out of existence. Another option would
be to make sure that the thresholds make sense, but keep all 4
threshold ranges, but you are the one who knows the details of how
these sizes impact performance...
Simplified a bit + fixed comments.
It feels odd to have all of the cache classes import the static
members of ArrayCache rather than just subclassing it. Is
there a
reason it wasn't just subclassed?
As all the members are static, I prefer having an explicit
static import
instead of subclasses.
Moreover, I deliberately avoided any class inheritance to avoid the
performance penalty of bimorphic / megamorphic method calls
(abstract or
overriden methods).
First, I would have expected MumbleArrayCache classes to be a
subclass of the ArrayCache class in the first place. If it is not
going to be the base class then it should have the name
"ArrayCacheUtils" or "Const" or something.
Renamed to ArrayCacheConst.
Second, wildcard imports are recommended against.
Finally, if you are going to use static methods from another class I
would much rather see explicit naming rather than importing them.
While static imports work for methods as well as constants, they are
typically used for constants and it is confusing to apply them to
methods.
Fixed.
The only reason is performance: I want to ensure straightforward
method
calls ie no bimorphic or virtual calls to be inlined by hotspot.
Maybe
such fear or approach is too conservative i.e. the performance
penalty
is too small to consider such optimization. I made many tests
with jmh
(in june) but I agree the design can be simpler:
- abstract [Byte/Int/Float]ArrayCache (where putArray() is abstract)
- Clean[Byte/Int/Float]ArrayCache and
Dirty[Byte/Int/Float]ArrayCache
implements properly the putArray method but also the createArray()
method (new array or Unsafe.allocateUninitializedArray)
I could try again but I prefer the current design as it is (overly)
strongly typed.
Please propose an alternative / simpler design !
That's something that can be investigated later as it would be a big
disruption for the current task. Generally, though, as long as the
leaf classes are final and the cache classes are strongly typed then
HS should inline freely.
I adopted a simple boolean flag 'clean' to perform the optional cleanup
and renamed classes to Byte/Float/Int ArrayCache.
Also, since you never put the initial arrays, they aren't
automatically cleaned...?
Exactly: initial arrays are allocated by the Reference class and
directly used by callers (fill / clean) and the XxxArrayCache never
touch them.
What I was getting at was that this was potentially a bug? If you
carry over use of an initial array in a clean setting without
calling to the cache object, then who clears the used portion?
All cases are manually cleaned in MarlinCache.resetTileLine(),
Renderer.dispose() and MarlinCache.copyAARowNoRLE...() for
alphaLine and
blkFlags arrays with several cleanup patterns (optimized and
performance-critical).
I see. Is this really a noticeable performance issue to rely on the
cache to do the cleaning and have much more readable code?
I adopted your proposal and simplified the code in Renderer: the
Reference.putArray() clears the array portion if needed in all cases.
The performance impact is very low: only 3% when the shape count is huge.
Cheers,
Laurent