ভেক্টর 2 -র ফলাফল কীভাবে অভিন্ন ইনপুট সহ 34 বার বলার পরে পরিবর্তিত হয়?


10

এখানে একটি সরল সি #। নেট কোর 3.1 প্রোগ্রাম রয়েছে যা System.Numerics.Vector2.Normalize()একটি লুপে কল করে (প্রতিটি কলকে অভিন্ন ইনপুট সহ) এবং ফলাফলটি সাধারণীকৃত ভেক্টর প্রিন্ট করে:

using System;
using System.Numerics;
using System.Threading;

namespace NormalizeTest
{
    class Program
    {
        static void Main()
        {
            Vector2 v = new Vector2(9.856331f, -2.2437377f);
            for(int i = 0; ; i++)
            {
                Test(v, i);
                Thread.Sleep(100);
            }
        }

        static void Test(Vector2 v, int i)
        {
            v = Vector2.Normalize(v);
            Console.WriteLine($"{i:0000}: {v}");
        }
    }
}

এবং এখানে আমার কম্পিউটারে সেই প্রোগ্রামটি চালানোর আউটপুট (ব্রেভিটির জন্য ছাঁটা):

0000: <0.9750545, -0.22196561>
0001: <0.9750545, -0.22196561>
0002: <0.9750545, -0.22196561>
...
0031: <0.9750545, -0.22196561>
0032: <0.9750545, -0.22196561>
0033: <0.9750545, -0.22196561>
0034: <0.97505456, -0.22196563>
0035: <0.97505456, -0.22196563>
0036: <0.97505456, -0.22196563>
...

সুতরাং আমার প্রশ্ন, 34 বার কল করার পরে কেন কল করার ফলাফল Vector2.Normalize(v)পরিবর্তন হয় ? এটি কি প্রত্যাশিত, বা এটি ভাষা / রানটাইমের কোনও বাগ?<0.9750545, -0.22196561><0.97505456, -0.22196563>



2
হয়তো @Milney, কিন্তু তারা করছি নির্ণায়ক । এই আচরণটি সম্পূর্ণরূপে অদ্ভুত হয়েই ব্যাখ্যা করা হয় না।
কনরাড রুডল্ফ

উত্তর:


14

সুতরাং আমার প্রশ্ন হ'ল ভেক্টরকে কল করার ফলাফল কেন? Or 34 বার কল করার পরে স্বাভাবিক (v) <0.9750545, -0.22196561> থেকে <0.97505456, -0.22196563> এ পরিবর্তন হয়?

সুতরাং প্রথম - কেন পরিবর্তন হয়। পরিবর্তিত পর্যবেক্ষণ করা হয় কারণ সেই মানগুলি গণনা করে এমন কোডও পরিবর্তিত হয়।

আমরা যদি কোডটির প্রথম সম্পাদনকারীদের প্রথম দিকে উইনডিবিজি ভাঙ্গি এবং কিছুটা নীচে Normalizeএড ভেক্টর গণনা করে এমন কোডের মধ্যে চলে যাই তবে আমরা নীচের সমাবেশটি দেখতে পেলাম (কমবেশি - আমি কিছু অংশ কেটে ফেলেছি):

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]

এবং ~ 30 মৃত্যুদণ্ড কার্যকর করার পরে (এই সংখ্যাটি সম্পর্কে আরও পরে) এই কোডটি হবে:

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

বিভিন্ন অপকড, বিভিন্ন এক্সটেনশন - এসএসই বনাম অ্যাভিএক্স এবং, আমার ধারণা, বিভিন্ন অপকডের সাথে আমরা গণনার আলাদা নির্ভুলতা পাই।

তাহলে এখন আরও কেন? । নেট কোর (সংস্করণ সম্পর্কে নিশ্চিত নয় - 3.0.০ ধরে ধরে - তবে এটি ২.১-এ পরীক্ষা করা হয়েছিল) এমন কিছু আছে যা "টাইার্ড জেআইটি সংকলন" নামে পরিচিত। এটি যা শুরুতে হয় তা কোড উত্পন্ন করে যা দ্রুত উত্পন্ন হয় তবে এটি সর্বোত্তম অনুকূল নাও হতে পারে। কেবলমাত্র পরে যখন রানটাইম সনাক্ত করে যে কোডটি অত্যন্ত ব্যবহৃত হয়েছে এটি নতুন, আরও অনুকূলিত কোড তৈরি করতে কিছু অতিরিক্ত সময় ব্যয় করবে। .NET কোর এ এটি একটি নতুন বিষয় তাই এর আগে এমন আচরণ সম্ভবত পর্যবেক্ষণ করা যায় না।

এছাড়াও 34 কল কেন? এটি কিছুটা অদ্ভুত যেহেতু আমি প্রায় 30 টি মৃত্যুদণ্ড কার্যকর হওয়ার আশা করব কারণ এটি এমন এক প্রান্তিক স্তর যেখানে সংকলন সংকলনটি লাথি মেরেছে core এই ধ্রুবকটি কোরক্লারের উত্স কোডটিতে দেখা যায় । এটি লাথি মারার সময় কিছু অতিরিক্ত পরিবর্তনশীলতা থাকতে পারে।

এই বিষয়টি নিশ্চিত হওয়ার জন্য, আপনি পরিবেশগত পরিবর্তনশীল সেট করে set COMPlus_TieredCompilation=0আবার কার্যকর করে পরীক্ষা করে পরীক্ষা করে টায়ার্ড সংকলন অক্ষম করতে পারেন । অদ্ভুত প্রভাব চলে গেছে।

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>

এটি কি প্রত্যাশিত, বা এটি ভাষা / রানটাইমের কোনও বাগ?

এর জন্য ইতিমধ্যে একটি বাগ রিপোর্ট করা হয়েছে - ইস্যু 1119


এটির কারণগুলির জন্য তাদের কোনও ক্লু নেই। আশা করি ওপি আপনার উত্তরটির লিঙ্কটি এখানে পোস্ট করতে পারে।
হ্যানস প্যাস্যান্ট

1
পুরো এবং তথ্যপূর্ণ উত্তরের জন্য ধন্যবাদ! এই বাগ রিপোর্টটি আসলে আমার প্রতিবেদন যা আমি এই প্রশ্নটি পোস্ট করার পরে দায়ের করেছি, এটি আসলে কোনও বাগ ছিল কিনা তা জেনেও না। তারা মনে করে যে পরিবর্তিত মানটিকে অযাচিত আচরণ বলে বিবেচনা করে যা হেইজনবগস এবং এমন কিছুর সমাধান করতে পারে যা হতে পারে।
ওয়াল্ট ডি

হ্যাঁ, সকাল 2 টায় বিশ্লেষণ করার আগে আমার রেপোটি চেক করা উচিত ছিল :) যাইহোক এটি সন্ধান করা আকর্ষণীয় সমস্যা ছিল।
পাউয়েউকেসিক

@ হ্যান্সপাস্যান্ট দুঃখিত, আপনি নিশ্চিত হন যে আমি কী করছি। আপনি দয়া করে পরিষ্কার করতে পারেন?
ওয়াল্ট ডি

সেই গিথুব ইস্যু আপনার দ্বারা পোস্ট করা হয়েছিল, তাই না? কেবল তাদের জানতে দিন যে তারা ভুল অনুমান করেছে।
হ্যানস প্যাস্যান্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.