Öyleyse sorum, Vector2.Normalize (v) çağrılmasının sonucu neden 34 kez çağırdıktan sonra <0.9750545, -0.22196561> 'den <0.97505456, -0.22196563>' e değişiyor?
Öyleyse ilk olarak - neden değişiklik meydana geliyor. Bu değerleri hesaplayan kod da değiştiği için bu değişiklik gözlemlenir.
WinDbg kodunun ilk yürütmelerinde erkenden girip Normalizeed vektörünü hesaplayan koda biraz inersek, aşağıdaki montajı görebilirdik (az çok - bazı parçaları kestim):
movss xmm0,dword ptr [rax]
movss xmm1,dword ptr [rax+4]
lea rax,[rsp+40h]
movss xmm2,dword ptr [rax]
movss xmm3,dword ptr [rax+4]
mulss xmm0,xmm2
mulss xmm1,xmm3
addss xmm0,xmm1
sqrtss xmm0,xmm0
lea rax,[rsp+40h]
movss xmm1,dword ptr [rax]
movss xmm2,dword ptr [rax+4]
xorps xmm3,xmm3
movss dword ptr [rsp+28h],xmm3
movss dword ptr [rsp+2Ch],xmm3
divss xmm1,xmm0
movss dword ptr [rsp+28h],xmm1
divss xmm2,xmm0
movss dword ptr [rsp+2Ch],xmm2
mov rax,qword ptr [rsp+28h]
ve ~ 30 yürütmeden sonra (daha sonra bu sayı hakkında daha fazla bilgi) bu kod olacaktır:
vmovsd xmm0,qword ptr [rsp+70h]
vmovsd qword ptr [rsp+48h],xmm0
vmovsd xmm0,qword ptr [rsp+48h]
vmovsd xmm1,qword ptr [rsp+48h]
vdpps xmm0,xmm0,xmm1,0F1h
vsqrtss xmm0,xmm0,xmm0
vinsertps xmm0,xmm0,xmm0,0Eh
vshufps xmm0,xmm0,xmm0,50h
vmovsd qword ptr [rsp+40h],xmm0
vmovsd xmm0,qword ptr [rsp+48h]
vmovsd xmm1,qword ptr [rsp+40h]
vdivps xmm0,xmm0,xmm1
vpslldq xmm0,xmm0,8
vpsrldq xmm0,xmm0,8
vmovq rcx,xmm0
Farklı opcodes, farklı uzantılar - SSE vs AVX ve sanırım, farklı opcodes ile hesaplamaların farklı hassasiyetlerini elde ederiz.
Şimdi neden hakkında daha fazla bilgi? .NET Core (sürümden emin değilim - 3.0 varsayarak - ancak 2.1'de test edildi) "Tiered JIT derlemesi" adı verilen bir şeye sahiptir. Yaptığı şey başlangıçta hızlı üretilen ancak süper optimal olmayan kod üretiyor. Ancak daha sonra çalışma zamanı, kodun çok kullanıldığını algıladığında, yeni ve daha optimize edilmiş kod oluşturmak için biraz zaman harcayacaktır. Bu, .NET Core'da yeni bir şeydir, bu nedenle bu davranış daha önce gözlemlenmeyebilir.
Ayrıca neden 34 çağrı? Bu, sıralı derlemenin başladığı eşik olduğu için 30 civarında yürütme olmasını beklediğim için biraz garip. Sabit, coreclr'ın kaynak kodunda görülebilir . Belki başladığında bazı ek değişkenlikler vardır.
Sadece durumun böyle olduğunu doğrulamak için set COMPlus_TieredCompilation=0, yürütmeyi yeniden düzenleyerek ve kontrol ederek çevresel değişkeni ayarlayarak katmanlı derlemeyi devre dışı bırakabilirsiniz . Garip etki gitti.
C:\Users\lukas\source\repos\FloatMultiple\FloatMultiple\bin\Release\netcoreapp3.1
λ FloatMultiple.exe
0000: <0,9750545 -0,22196561>
0001: <0,9750545 -0,22196561>
0002: <0,9750545 -0,22196561>
...
0032: <0,9750545 -0,22196561>
0033: <0,9750545 -0,22196561>
0034: <0,9750545 -0,22196561>
0035: <0,97505456 -0,22196563>
0036: <0,97505456 -0,22196563>
^C
C:\Users\lukas\source\repos\FloatMultiple\FloatMultiple\bin\Release\netcoreapp3.1
λ set COMPlus_TieredCompilation=0
C:\Users\lukas\source\repos\FloatMultiple\FloatMultiple\bin\Release\netcoreapp3.1
λ FloatMultiple.exe
0000: <0,97505456 -0,22196563>
0001: <0,97505456 -0,22196563>
0002: <0,97505456 -0,22196563>
...
0032: <0,97505456 -0,22196563>
0033: <0,97505456 -0,22196563>
0034: <0,97505456 -0,22196563>
0035: <0,97505456 -0,22196563>
0036: <0,97505456 -0,22196563>
Bu bekleniyor mu, yoksa bu dil / çalışma zamanında bir hata mı?
Bunun için zaten bir hata bildirildi - Sayı 1119