-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Dart VM does not preserve identities for SIMD objects #43255
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
Comments
/cc @mkustermann for triage |
@cskau-g Could you take a look at this? |
This test appears to fail for all variants: Dumping the kernel (Looks OK):
Printing the CFG from the .dart file (Looks OK):
Disassembling (Not OK):
From what I can tell, something is broken in the ASM generation/optimisation. @mkustermann, perhaps you have some ideas where we might go looking for bug on this? (Note: I swapped two of the test cases in the above code, but the issue remains the same.) |
I suggest that we maybe change the expected semantics here and maybe the test itself.
@lrhn @leafpetersen I would be helpful for us if SIMD types got the same treatment as records in terms of identity (e.g. VM would not need to preserve their identity). Currently there is nothing in their documentation which allows for such treatment, and we in fact violate it in few places (like this test shows for example). |
@mraleph So you're suggestion changing the The only reason the SIMD type cannot be a record/tuple type itself is that its elements don't have a Dart type, and we can't use So, do we want a way to declare a class as a "record class" ( |
Yes, except that constructor is not obliged to canonicalize because identity is not observable. So it might be canonicalizing might be not. Essentially I propose to treat simd types the same way we treat
That might be helpful, I have already considered experimenting with this because there are some use cases when this can be helpful, e.g.
Hard to say about JS though (though I think that most of the compile-to-JS code does not actually use SIMD types because they don't come with any performance benefits) - any opinions on the subject @rakudrama? |
There were some efforts to add SIMD types to JavaScript, but they have been abandoned (the action is in WebAssembly). It would be interesting to allow GVN optimizations for allocations of some 'record' types. I don't want to add code to Where I want loose identity in my everyday life is with unmodifiable collections. |
Marking this as blocked - since we're waiting for language team to decide whether those SIMD types can be treated differently regarding to |
The quick answer is that they can't be treated differently. Nothing in the current language allows that. The question is whether we want to add an exception, and if so, how would we phrase that? |
There's nothing saying or indicating that a default equality operator should be always treated as an What's happening here is that I think that It's also not intuitive to have operations with |
@lrhn @leafpetersen is it possible to bump this into language team agenda? What we would like here is to permit implementations to loose the identity of SIMD objects, either as a language change targeting specifically these types or something slightly wider (e.g. Currently VM already partially looses identity of SIMD types, however this obviously violates the spec. The choice we have now is either to fix implementation to conform or amend the specification. We did these optimisations back in the day without realising that spec did not expand its treatment of numeric types to SIMD types (which seems natural to do). Note that current specification essentially limits us to local unboxing (or rather allocation sinking - which unlike unboxing preserves identity), and does not allow us to unbox fields, parameters and return values. |
The only real purpose of 'Float32x4' is the SIMD optimization. Anything that reduces the SIMD performance or reduces the global performance of a Dart code that will be "adapted" in VM/AOT to use SIMD instructions is against the actual existence of 'Float32x4'. The use of 'identity' in a type that depends on factory constructors is already odd. Also perform an 'identity' check in 'Float32x4' should be strange like perform that in a double. |
The issue is a bit more subtle that this - it's not really about whether the same (factory) constructor invocation returns two different instances or the same instance. It is about whether an identity of an instance can be lost as it travels through the program: Float32x4 foo(Float32x4 o) => o;
Object bar(Object o) => foo(o as Float32x4);
void main() {
final o = Float32x4(...);
print(identical(o, bar(o)));
} If you replace |
I strongly suggest to forget about 'identical' for 'Float32x4', since the overhead to keep it reduces a lot the usage of 'Float32x4' and destroys GC for intensive SIMD tasks. It's something that goes against the existence of SIMD support in Dart. Also there's no real usage of 'identical' for types like that. |
@gmpassos yes, that what I suggest as well, but the decision needs to be made by the language team in the end, so we just wait for the them to discuss this issue and respond. All the necessary arguments were made. |
I think that the code that need to be changed is small and easy to test. The point is much more about a team decision and to get the right people to discuss, specially about real case scenarios. Remember that with the current language definition, a small immutable object (Float32x4) is destroying the GC for an intensive computation task that uses SIMD, and this is the real use case for this kind of type. A loop of multiplications should not generate new heap allocations. |
I am trying to move this forward in dart-lang/language#2246 |
The following test fail on
dartkp-strong-linux-release-simarm64
configurationOutput is
The text was updated successfully, but these errors were encountered: