কেন মরিচা সংকলক কোডটি দুটি অপরিবর্তনীয় রেফারেন্সের উপনামটি দিতে পারে না এই ধারণা করে কোডটি অপ্টিমাইজ করে না?


301

যতদূর আমি জানি, রেফারেন্স / পয়েন্টার আলিয়াসিং সংকলকটির অনুকূলিত কোড উত্পন্ন করার ক্ষমতা বাধাগ্রস্ত করতে পারে, যেহেতু অবশ্যই তাদের অবশ্যই জেনারেটেড বাইনারি ক্ষেত্রে সঠিকভাবে আচরণ করে যেখানে দুটি রেফারেন্স / পয়েন্টার প্রকৃতরূপে উপনাম রয়েছে ensure উদাহরণস্বরূপ, নিম্নলিখিত সি কোডে,

void adds(int  *a, int *b) {
    *a += *b;
    *a += *b;
}

পতাকা clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)সহ যখন সংকলন করা হয় তখন -O3তা নির্গত হয়

0000000000000000 <adds>:
   0:    8b 07                    mov    (%rdi),%eax
   2:    03 06                    add    (%rsi),%eax
   4:    89 07                    mov    %eax,(%rdi)  # The first time
   6:    03 06                    add    (%rsi),%eax
   8:    89 07                    mov    %eax,(%rdi)  # The second time
   a:    c3                       retq

এখানে কোড (%rdi)দু'বার ক্ষেত্রে int *aএবং int *bউলামে ফিরে আসে ।

আমরা যখন স্পষ্টভাবে সংকলককে বলি যে এই দুটি পয়েন্টার মূল শব্দটির সাথে উপনাম করতে পারে না restrict:

void adds(int * restrict a, int * restrict b) {
    *a += *b;
    *a += *b;
}

তারপরে ক্ল্যাং বাইনারি কোডের আরও অনুকূলিত সংস্করণ প্রস্থান করবে:

0000000000000000 <adds>:
   0:    8b 06                    mov    (%rsi),%eax
   2:    01 c0                    add    %eax,%eax
   4:    01 07                    add    %eax,(%rdi)
   6:    c3                       retq

যেহেতু মর্ট নিশ্চিত করেছে (অনিরাপদ কোড ব্যতীত) যে দুটি মিউটেবল রেফারেন্স উলেস করতে পারে না, তাই আমি মনে করি যে সংকলকটি কোডটির আরও অনুকূলিত সংস্করণ নির্গত করতে সক্ষম হবে।

যখন আমি নিচের কোড দিয়ে পরীক্ষা এবং সঙ্গে এটি কম্পাইল rustc 1.35.0সঙ্গে -C opt-level=3 --emit obj,

#![crate_type = "staticlib"]
#[no_mangle]
fn adds(a: &mut i32, b: &mut i32) {
    *a += *b;
    *a += *b;
}

এটি উত্পন্ন:

0000000000000000 <adds>:
   0:    8b 07                    mov    (%rdi),%eax
   2:    03 06                    add    (%rsi),%eax
   4:    89 07                    mov    %eax,(%rdi)
   6:    03 06                    add    (%rsi),%eax
   8:    89 07                    mov    %eax,(%rdi)
   a:    c3                       retq

এটি গ্যারান্টিটির সদ্ব্যবহার করে না aএবং bউপনাম করতে পারে না।

এটি কি কারণ বর্তমান মরিচা সংকলকটি এখনও বিকাশে রয়েছে এবং অপ্টিমাইজেশানটি করতে এখনও ওরফে বিশ্লেষণকে অন্তর্ভুক্ত করেনি?

এটি কি কারণ এখনও এমন একটি সম্ভাবনা রয়েছে যা নিরাপদ মরচেও থাকতে পারে aএবং bউরফ করতে পারে?



76
পার্শ্বের মন্তব্য: " যেহেতু মরশুম নিশ্চিত করে (অনিরাপদ কোড ব্যতীত) যে দুটি পার্সোনাল রেফারেন্স উলেফ করতে পারে না " - এটি উল্লেখযোগ্য যে এমনকি unsafeকোডেও, পরিবর্তনশীল রেফারেন্স অনুমোদিত নয় এবং ফলস্বরূপ অপরিবর্তিত আচরণের ফলস্বরূপ। আপনার কাঁচা পয়েন্টারগুলি আলিয়াসিং থাকতে পারে তবে unsafeকোডটি আসলে আপনাকে মরিচা স্ট্যান্ডার্ড বিধিগুলি উপেক্ষা করার অনুমতি দেয় না। এটি কেবল একটি সাধারণ ভ্রান্ত ধারণা এবং এইভাবে দেখানো মূল্যবান।
লুকাশ কালবার্টডট

6
উদাহরণটি কী পাচ্ছে তা নির্ধারণ করতে আমার কিছুটা সময় লেগেছিল, কারণ আমি asm পড়তে দক্ষ নই, সুতরাং এটি অন্য কাউকে সহায়তা করে: এটি +=শরীরের দুটি ক্রিয়াকলাপকে পুনরায় ব্যাখ্যা করা addsযেতে পারে কিনা তা নিয়ে এটি ফুটে উঠেছে *a = *a + *b + *b। পয়েন্টার ওরফে না, তাহলে তারা, আপনি এমনকি দেখতে পারেন কি পরিমাণ b* + *bদ্বিতীয় তালিকা এ এস এম দেখুন: 2: 01 c0 add %eax,%eax। তবে তারা যদি উপনামটি করেন তবে তারা পারবেন না, কারণ আপনি *bদ্বিতীয়বার যুক্ত করার সময় এর মধ্যে প্রথমবারের চেয়ে আলাদা মান থাকবে (আপনি 4:প্রথম asm তালিকার লাইনে যেটি সঞ্চয় করেন )।
dlukes

উত্তর:


364

মরিচাটি মূলত এলএলভিএম এর বৈশিষ্ট্য সক্ষম করেছিলnoalias , তবে এটি ভুল সংকলিত কোডের কারণে । যখন সমস্ত সমর্থিত এলএলভিএম সংস্করণগুলি কোডটির আর ভুল সংকলন করে না, এটি পুনরায় সক্ষম করা হবে

আপনি যদি -Zmutable-noalias=yesসংকলক বিকল্পগুলিতে যোগ করেন তবে আপনি প্রত্যাশিত সমাবেশ পাবেন:

adds:
        mov     eax, dword ptr [rsi]
        add     eax, eax
        add     dword ptr [rdi], eax
        ret

সহজ কথায় বলতে গেলে, জাস্ট যেকোন সি সি প্রোগ্রামের চেয়ে অনেক বেশি প্রচলিত, সর্বত্র সি এর restrictকীওয়ার্ডের সমতুল্য রাখে । এই এলএলভিএমের অনুশীলন কর্নার কেসগুলি সঠিকভাবে পরিচালনা করতে সক্ষম হওয়ার চেয়ে বেশি। এটি দেখা যাচ্ছে যে সি এবং সি ++ প্রোগ্রামারগুলি কেবল মরিচায় ব্যবহৃত হিসাবে ঘন ঘন ব্যবহার করে না।restrict&mut

এটি একাধিকবার ঘটেছে ।

  • মরিচা 1.0 মাধ্যমে 1.7 - noaliasসক্ষম
  • মরিচা 1.8 এর মাধ্যমে 1.27 - noaliasঅক্ষম
  • মরিচা 1.28 এর মাধ্যমে 1.29 - noaliasসক্ষম
  • মরিচা 1.30 এর মাধ্যমে ??? - noaliasঅক্ষম

সম্পর্কিত জং সমস্যা


12
এটি অবাক করা কিছু নয়। এর বহু-ভাষা-বন্ধুত্বের বিস্তৃত দাবী সত্ত্বেও, এলএলভিএমকে বিশেষত একটি সি ++ ব্যাকএন্ড হিসাবে নকশা করা হয়েছিল এবং এটি সি ++ এর মতো দেখতে যথেষ্ট লাগে না এমন জিনিসগুলিতে শ্বাসরোধ করার দৃ always় প্রবণতা রয়েছে।
ম্যাসন হুইলারের 21

47
@ ম্যাসনভিয়েল আপনি যদি কিছু সমস্যার জন্য ক্লিক করেন তবে আপনি সি কোডের উদাহরণ খুঁজে পাবেন যা restrictক্ল্যাং এবং জিসিসি উভয়ই ব্যবহার করে এবং ভুল সংকলন করে। আপনি কেবলমাত্র সেই গ্রুপে সি ++ গণনা না করে, "সি ++ পর্যাপ্ত" নয় এমন ভাষার মধ্যে সীমাবদ্ধ নয় ।
শেপমাস্টার

6
@ মেসনভিয়েল: আমি মনে করি না এলএলভিএম সত্যই সি বা সি ++ এর নিয়মের আশেপাশে তৈরি হয়েছিল, বরং এলএলভিএমের নিয়মের আশেপাশে। এটি এমন অনুমানগুলি তৈরি করে যা সাধারণত সি বা সি ++ কোডের ক্ষেত্রে সত্য হয়, তবে আমি যা ডিজাইন বলতে পারি তা স্থির-ডেটা-নির্ভরতা মডেলটির উপর পূর্বাভাস দেওয়া হয় যা জটিল কোণার কেসগুলি পরিচালনা করতে পারে না। এটি ঠিক আছে যদি এটি বিশ্বাসহীনভাবে ডেটা নির্ভরতা ধরে নেওয়া যায় যা অস্বীকার করা যায় না, তবে পরিবর্তে এটি কোনও অপ্সের ক্রিয়া হিসাবে বিবেচনা করে যা এটি ধারণ করে একই বিট প্যাটার্নের সাথে স্টোরেজ লিখবে, এবং যার সম্ভাব্য তবে প্রমাণযোগ্য নয় ডেটা নির্ভরতা পড়ুন এবং লিখুন।
ক্যাট

8
@ সুপের্যাট আমি আপনার মন্তব্যগুলি কয়েকবার পড়েছি, তবে আমি স্বীকার করছি যে আমি স্ট্যাম্পড হয়েছি - এই প্রশ্ন বা উত্তর দিয়ে তাদের কী করতে হবে তা আমার কোনও ধারণা নেই। অপরিবর্তিত আচরণ এখানে খেলতে আসে না, এটি "কেবল" একাধিক অপ্টিমাইজেশনের ক্ষেত্রে একে অপরের সাথে দুর্বলভাবে ইন্টারঅ্যাক্ট করার পাস।
শেপমাস্টার

2
@ ওএল_স্বামী পুনরাবৃত্তি করতে, এটি কেবল একটি বাগ । লুপ আনরোলিং অপটিমাইজেশন পদক্ষেপটি কার্যকর করে ( noaliasপয়েন্টারগুলি ) সম্পূর্ণরূপে পয়েন্টারগুলিকে বিবেচনা করে না? এটি ইনপুট পয়েন্টারগুলির উপর ভিত্তি করে নতুন পয়েন্টার তৈরি করেছে, noaliasনতুন পয়েন্টারগুলির উপাম থাকলেও, অ্যাট্রিবিউটটি ভুলভাবে অনুলিপি করে ।
শেপমাস্টার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.