just a thought.. imo using identity hash field for instances of Float while probable, but in fact really impractical.
in that sense, what you think about removing filling the identity hash field and leave it always == 0.. saving some instructions to make float allocation a bit faster?
i am talking about genAllocFloatValue: dpreg into: resultReg scratchReg: scratch1 scratchReg: scratch2
On 2013-07-29, at 23:59, Igor Stasenko siguctua@gmail.com wrote:
just a thought.. imo using identity hash field for instances of Float while probable, but in fact really impractical.
in that sense, what you think about removing filling the identity hash field and leave it always == 0.. saving some instructions to make float allocation a bit faster?
i am talking about genAllocFloatValue: dpreg into: resultReg scratchReg: scratch1 scratchReg: scratch2
IMHO, turning Floats into the only objects in the system that cause severe collisions in IdentitySets / Dictionaries should not be done lightly. It's a step away from "every object is equal" which I think is an important principle.
The VM should only "cheat without getting caught", as Dan put it. And there are options for that.
For example, the better our JIT gets, the less intermediate floats need to be allocated because you can avoid boxing/unboxing them altogether, so that's an even larger win.
And if we switched to immediate floats (e.g. in the 64 bit image format) the allocation issue would go away completely.
I'm still curious: Assuming you tried it already, what kind of speedup do you get?
- Bert -
On 30 July 2013 00:23, Bert Freudenberg bert@freudenbergs.de wrote:
On 2013-07-29, at 23:59, Igor Stasenko siguctua@gmail.com wrote:
just a thought.. imo using identity hash field for instances of Float while probable, but in fact really impractical.
in that sense, what you think about removing filling the identity hash field and leave it always == 0.. saving some instructions to make float allocation a bit faster?
i am talking about genAllocFloatValue: dpreg into: resultReg scratchReg: scratch1 scratchReg: scratch2
IMHO, turning Floats into the only objects in the system that cause severe collisions in IdentitySets / Dictionaries should not be done lightly. It's a step away from "every object is equal" which I think is an important principle.
The VM should only "cheat without getting caught", as Dan put it. And there are options for that.
For example, the better our JIT gets, the less intermediate floats need to be allocated because you can avoid boxing/unboxing them altogether, so that's an even larger win.
And if we switched to immediate floats (e.g. in the 64 bit image format) the allocation issue would go away completely.
perhaps then it makes sense to also modify identityHash primitive to check if receiver is Float and use float value for it? Then there is no collisions/cheating, and little speedup in floats allocation? So identityHash primitive wear additional cost with checking that header is actually compactfloat. But given the amount of floats "floating around" :) comparing how often #identityHash is used, i think it is fair tradeoff.
I'm still curious: Assuming you tried it already, what kind of speedup do you get?
i did not tried.
- Bert -
On Mon, Jul 29, 2013 at 5:23 PM, Bert Freudenberg bert@freudenbergs.de wrote:
On 2013-07-29, at 23:59, Igor Stasenko siguctua@gmail.com wrote:
just a thought.. imo using identity hash field for instances of Float while probable, but in fact really impractical.
in that sense, what you think about removing filling the identity hash field and leave it always == 0.. saving some instructions to make float allocation a bit faster?
i am talking about genAllocFloatValue: dpreg into: resultReg scratchReg: scratch1 scratchReg: scratch2
IMHO, turning Floats into the only objects in the system that cause severe collisions in IdentitySets / Dictionaries should not be done lightly. It's a step away from "every object is equal" which I think is an important principle.
+1. I recently was investigating memory consumption in a large application image and discovered > 100MB in Float instances..!! But guess what, many many of them were the same number (0.0, 1.0, 100.0, -100.0, and several others had many occurrences) -- prompting me to wonder whether I should try to canonicalize them upon materialization, via an IdentityDictionary..
I haven't tried it yet but.. if their identityHash'es were all 0 then it'd be pointless to try.
So I like your other idea about using the float itself as the identityHash, however that would be done, at least they'd be unique and consistent.
On 30 July 2013 23:37, Chris Muller asqueaker@gmail.com wrote:
On Mon, Jul 29, 2013 at 5:23 PM, Bert Freudenberg bert@freudenbergs.de wrote:
On 2013-07-29, at 23:59, Igor Stasenko siguctua@gmail.com wrote:
just a thought.. imo using identity hash field for instances of Float while probable, but in fact really impractical.
in that sense, what you think about removing filling the identity hash field and leave it always == 0.. saving some instructions to make float allocation a bit faster?
i am talking about genAllocFloatValue: dpreg into: resultReg scratchReg: scratch1 scratchReg: scratch2
IMHO, turning Floats into the only objects in the system that cause severe collisions in IdentitySets / Dictionaries should not be done lightly. It's a step away from "every object is equal" which I think is an important principle.
+1. I recently was investigating memory consumption in a large application image and discovered > 100MB in Float instances..!! But guess what, many many of them were the same number (0.0, 1.0, 100.0, -100.0, and several others had many occurrences) -- prompting me to wonder whether I should try to canonicalize them upon materialization, via an IdentityDictionary..
I haven't tried it yet but.. if their identityHash'es were all 0 then it'd be pointless to try.
right now it will be pointless as well, since
0.0 identityHash ~= 0.0 identityHash
and for canonization you have to use Dictionary which uses #hash, not identity hash.
So I like your other idea about using the float itself as the identityHash, however that would be done, at least they'd be unique and consistent.
hashes are not unique by definition, they are just need to be "unique enough" to not collide much often.
So far, there is only one dictionary which uses floats as keys:
(Dictionary allSubInstances select: [:dict | dict keys anySatisfy: [:key | key isFloat ] ] ) size 1
That the only dictionary used in Pharo by SHTextStyler textAttributesByPixelHeight, and i think it rather bug/coincidence, since pixel height usually integer number.
Ah, yes.. and this is dictionary, not identity dictionary, using #hash for keys anyways.
(Set allSubInstances select: [:set | set anySatisfy: [:key | key isFloat ] ] ) size
0
But i agree, i can imagine that for things like Magma, you need to use them as keys..
On 31 July 2013 04:17, Igor Stasenko siguctua@gmail.com wrote:
On 30 July 2013 23:37, Chris Muller asqueaker@gmail.com wrote:
On Mon, Jul 29, 2013 at 5:23 PM, Bert Freudenberg bert@freudenbergs.de wrote:
On 2013-07-29, at 23:59, Igor Stasenko siguctua@gmail.com wrote:
just a thought.. imo using identity hash field for instances of Float while probable, but in fact really impractical.
in that sense, what you think about removing filling the identity hash field and leave it always == 0.. saving some instructions to make float allocation a bit faster?
i am talking about genAllocFloatValue: dpreg into: resultReg scratchReg: scratch1 scratchReg: scratch2
IMHO, turning Floats into the only objects in the system that cause severe collisions in IdentitySets / Dictionaries should not be done lightly. It's a step away from "every object is equal" which I think is an important principle.
+1. I recently was investigating memory consumption in a large application image and discovered > 100MB in Float instances..!! But guess what, many many of them were the same number (0.0, 1.0, 100.0, -100.0, and several others had many occurrences) -- prompting me to wonder whether I should try to canonicalize them upon materialization, via an IdentityDictionary..
I haven't tried it yet but.. if their identityHash'es were all 0 then it'd be pointless to try.
right now it will be pointless as well, since
0.0 identityHash ~= 0.0 identityHash
sorry i meant
0.0 identityHash ~= 0.0 copy identityHash
and for canonization you have to use Dictionary which uses #hash, not identity hash.
So I like your other idea about using the float itself as the identityHash, however that would be done, at least they'd be unique and consistent.
hashes are not unique by definition, they are just need to be "unique enough" to not collide much often.
So far, there is only one dictionary which uses floats as keys:
(Dictionary allSubInstances select: [:dict | dict keys anySatisfy: [:key | key isFloat ] ] ) size 1
That the only dictionary used in Pharo by SHTextStyler textAttributesByPixelHeight, and i think it rather bug/coincidence, since pixel height usually integer number.
Ah, yes.. and this is dictionary, not identity dictionary, using #hash for keys anyways.
(Set allSubInstances select: [:set | set anySatisfy: [:key | key isFloat ] ] ) size
0
But i agree, i can imagine that for things like Magma, you need to use them as keys..
-- Best regards, Igor Stasenko.
vm-dev@lists.squeakfoundation.org