কিছুক্ষণের জন্য অপ্টিমাইজ করা (") (1)" সি ++ 0x এ


153

আপডেট হয়েছে, নীচে দেখুন!

আমি শুনেছি এবং পড়েছি যে সি ++ 0x একটি সংকলককে নিম্নলিখিত স্নিপেটের জন্য "হ্যালো" মুদ্রণের অনুমতি দেয়

#include <iostream>

int main() {
  while(1) 
    ;
  std::cout << "Hello" << std::endl;
}

থ্রেড এবং অপ্টিমাইজেশনের ক্ষমতাগুলির সাথে এর স্পষ্টতই কিছু করার রয়েছে। এটি আমার কাছে দেখে মনে হচ্ছে এটি যদিও বহু লোককে অবাক করে তুলতে পারে।

কেন এটির অনুমতি দেওয়া প্রয়োজন তা সম্পর্কে কারও কি ভাল ব্যাখ্যা আছে? রেফারেন্সের জন্য, সর্বাধিক সাম্প্রতিক সি ++ 0x খসড়াটি এতে বলেছে6.5/5

একটি লুপ, স্টেটমেন্টের ক্ষেত্রে ফর স্টেটমেন্টের বাইরে স্টেটমেন্টের ক্ষেত্রে,

  • লাইব্রেরিতে I / O ফাংশনগুলিতে কোনও কল দেয় না এবং
  • অস্থির বস্তু অ্যাক্সেস বা সংশোধন করে না, এবং
  • কোনও সিঙ্ক্রোনাইজেশন অপারেশন (1.10) বা পারমাণবিক ক্রিয়াকলাপ সম্পাদন করে না (ধারা 29)

সমাপ্তকরণ বাস্তবায়ন দ্বারা ধরে নেওয়া যেতে পারে। [দ্রষ্টব্য: এটি সমাপ্তি প্রমাণিত না হওয়া সত্ত্বেও খালি লুপগুলি অপসারণের মতো সংকলক ট্রান্সফরমেশনগুলি অনুমোদনের উদ্দেশ্যে। - শেষ নোট]

সম্পাদনা:

এই অন্তর্দৃষ্টিপূর্ণ নিবন্ধটি সেই মানক পাঠ্য সম্পর্কে বলে

দুর্ভাগ্যক্রমে, "অপরিজ্ঞাত আচরণ" শব্দ ব্যবহার করা হয়নি। যাইহোক, মানক যে কোনও সময় "সংকলক পি ধরে নিতে পারে" বলে বোঝানো হয়েছে যে কোনও প্রোগ্রামের মধ্যে পি-র সম্পত্তি নেই এমন একটি শব্দার্থবিজ্ঞান রয়েছে।

এটি কি সঠিক, এবং সংকলককে কি উপরের প্রোগ্রামটির জন্য "বাই" মুদ্রণের অনুমতি দেওয়া হয়েছে?


এখানে আরও একটি অন্তর্দৃষ্টিপূর্ণ থ্রেড রয়েছে , যা সি এর সাথে অভিন্ন পরিবর্তন সম্পর্কে, উপরের লিঙ্কযুক্ত নিবন্ধটি গাই দ্বারা শুরু হয়েছিল। অন্যান্য দরকারী তথ্যগুলির মধ্যে, তারা এমন একটি সমাধান উপস্থাপন করে যা দেখে মনে হয় যে এটি সি ++ 0x- এও প্রযোজ্য ( আপডেট : এটি এন 3225 দিয়ে আর কাজ করবে না - নীচে দেখুন!)

endless:
  goto endless;

কোনও সংকলককে এটিকে অপ্টিমাইজ করার অনুমতি নেই, মনে হয় এটি কোনও লুপ নয়, তবে একটি লাফ। আরেকটি লোক সি ++ 0 এক্স এবং সি201 এক্স-এর প্রস্তাবিত পরিবর্তনের সংক্ষিপ্তসার জানায়

একটি লুপ লিখে, প্রোগ্রামারটি হয় যে লুপটি দৃশ্যমান আচরণ (আই / ও সম্পাদন করে, অস্থিতিশীল বস্তুগুলি অ্যাক্সেস করে, বা সিঙ্ক্রোনাইজেশন বা পারমাণবিক ক্রিয়াকলাপ সম্পাদন করে) দিয়ে কিছু করে, বা এটি শেষ অবধি সমাপ্ত হয় either যদি আমি কোনও পার্শ্ব প্রতিক্রিয়া ছাড়াই অসীম লুপ লিখে সেই অনুমানটিকে লঙ্ঘন করি তবে আমি কম্পাইলারের কাছে মিথ্যা বলছি, এবং আমার প্রোগ্রামের আচরণটি অপরিজ্ঞাত। (আমি ভাগ্যবান হলে, সংকলকটি আমাকে এ সম্পর্কে সতর্ক করতে পারে)) ভাষা দৃশ্যমান আচরণ ছাড়াই অসীম লুপটি প্রকাশ করার উপায় সরবরাহ করে না (আর সরবরাহ করে না?)।


N3225 সহ 3.1.2011 এ আপডেট করুন: কমিটি পাঠ্যটিকে 1.10 / 24 এ স্থানান্তরিত করে বলে

বাস্তবায়ন ধরে নেওয়া যেতে পারে যে কোনও থ্রেড অবশেষে নিম্নলিখিতগুলির মধ্যে একটি করবে:

  • বিনষ্ট,
  • I / O ফাংশনটিতে একটি লাইব্রেরিতে কল করুন
  • একটি অস্থির বস্তু অ্যাক্সেস বা সংশোধন করুন, বা
  • একটি সিঙ্ক্রোনাইজেশন অপারেশন বা একটি পারমাণবিক অপারেশন সঞ্চালন।

gotoকৌতুক হবে না আর কাজ!


4
while(1) { MyMysteriousFunction(); }সেই রহস্যময় ফাংশনটির সংজ্ঞা না জেনে স্বাধীনভাবে সংকলনযোগ্য হতে হবে, তাই না? সুতরাং এটি নির্ধারণ করতে পারি যে এটি কোনও লাইব্রেরির I / O ফাংশনগুলিতে কল করে কিনা? অন্য কথায়: অবশ্যই প্রথম বুলেটটি ফাংশন করা যেতে পারে কোন ক্রিয়াকলাপের জন্য কোনও কল দেয় না
ড্যানিয়েল আরউইকার

19
@ ড্যানিয়েল: যদি এতে ফাংশনের সংজ্ঞায় অ্যাক্সেস থাকে তবে এটি অনেক কিছু প্রমাণ করতে পারে। ইন্টারপ্রেসিডুরাল অপটিমাইজেশন হিসাবে একটি জিনিস আছে।
পোটোসওয়টার

3
এই মুহুর্তে, সি ++ 03 তে, কোনও সংকলককে কি এতে int x = 1; for(int i = 0; i < 10; ++i) do_something(&i); x++;রূপান্তর করার অনুমতি দেওয়া হচ্ছে for(int i = 0; i < 10; ++i) do_something(&i); int x = 2;? অথবা সম্ভবত অন্যভাবে, লুপের আগে xসূচনা করার সাথে 2। এটি বলতে do_somethingপারে যে এর মান সম্পর্কে কোন চিন্তা করে না x, সুতরাং এটি একেবারে নিরাপদ অপ্টিমাইজেশান, যদি do_something এর মূল্য iপরিবর্তন না করে যদি আপনি অসীম লুপে পৌঁছে যান।
ডেনিস জিকিফুজ

4
সুতরাং এর অর্থ কি এই যে main() { start_daemon_thread(); while(1) { sleep(1000); } }কোনও পটভূমির থ্রেডে আমার ডেমন চালানোর পরিবর্তে তাত্ক্ষণিকভাবে প্রস্থান করা যেতে পারে?
গাবে

2
"এই অন্তর্দৃষ্টিপূর্ণ নিবন্ধ" ধরে নিয়েছে যে একটি নির্দিষ্ট আচরণ কেবল স্পষ্ট, সংজ্ঞায়িত আচরণ নেই বলেই একটি সংজ্ঞায়িত আচরণ is এটি একটি ভুল ধারণা। সাধারণভাবে, যখন স্ট্যান্ডার্ড পাতাগুলি একটি সীমাবদ্ধ আচরণের সীমাবদ্ধ করে, একটি কার্যকরকরণ অবশ্যই তাদের ( অনির্ধারিত আচরণ) যেকোনটি বেছে নিতে পারে। এগুলি নিরঙ্কুশ হওয়ার দরকার নেই। ডু-কিছুই না লুপ সমাপ্ত হয় কিনা তর্কাতীতভাবে একটি বুলিয়ান পছন্দ; হয় তা করে না হয় না। অন্য কিছু করার অনুমতি নেই।
এমসাল্টার

উত্তর:


33

কেন এটির অনুমতি দেওয়া প্রয়োজন তা সম্পর্কে কারও কি ভাল ব্যাখ্যা আছে?

হ্যাঁ, হান্স বোহম এন 1528 এ এর জন্য একটি যুক্তি সরবরাহ করে : অসীম লুপগুলির জন্য কেন অপরিজ্ঞাত আচরণ? যদিও এটি ডাব্লুজি 14 নথি, যুক্তিটি সি ++ তেও প্রযোজ্য এবং নথিতে ডাব্লুজি 14 এবং ডাব্লুজি 21 উভয়ই বোঝানো হয়েছে:

যেমন N1509 সঠিকভাবে উল্লেখ করেছে, বর্তমান খসড়াটি মূলত 6.8.5p6 এ অসীম লুপগুলিকে অপরিজ্ঞাত আচরণ দেয়। এটি করার জন্য একটি বড় সমস্যা হ'ল এটি কোডটি একটি সম্ভাব্য অ-টার্মিনেটিং লুপের ওপারে সরে যাওয়ার অনুমতি দেয়। উদাহরণস্বরূপ, ধরে নিন আমাদের নীচের লুপগুলি রয়েছে, যেখানে গণনা এবং গণনা 2 হ'ল বৈশ্বিক চলক (বা তাদের ঠিকানা নেওয়া হয়েছিল), এবং পি স্থানীয় ভেরিয়েবল, যার ঠিকানা নেওয়া হয়নি:

for (p = q; p != 0; p = p -> next) {
    ++count;
}
for (p = q; p != 0; p = p -> next) {
    ++count2;
}

এই দুটি লুপগুলি কি নিম্নলিখিত লুপ দ্বারা একত্রিত এবং প্রতিস্থাপন করা যেতে পারে?

for (p = q; p != 0; p = p -> next) {
        ++count;
        ++count2;
}

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

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

টার্মিনেটিং লুপ দ্বারা আরোপিত বিধিনিষেধগুলি টার্মিনেটিং লুপগুলির অপ্টিমাইজেশানের উপর একটি বিধিনিষেধ, যার জন্য সংকলক সমাপ্তি প্রমাণ করতে পারে না, পাশাপাশি প্রকৃতপক্ষে অ-অবসানকারী লুপগুলির অনুকূলিতকরণের ক্ষেত্রেও। পূর্ববর্তীগুলি পরবর্তীকালের চেয়ে অনেক বেশি সাধারণ এবং প্রায়শই আরও অনুকূল করা অনুকূল।

একটি পূর্ণসংখ্যার লুপ ভেরিয়েবল সহ স্পষ্টভাবে লুপগুলি রয়েছে যা সংকলকটির পক্ষে সমাপ্তি প্রমাণিত করা কঠিন এবং এইভাবে সংকলকটির পক্ষে 6.8.5p6 ছাড়াই লুপগুলি পুনর্গঠন করা কঠিন হবে। এমনকি কিছু

for (i = 1; i != 15; i += 2)

অথবা

for (i = 1; i <= 10; i += j)

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

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

সি এর সাথে একটি প্রধান পার্থক্য হ'ল সি 11 ধ্রুবক প্রকাশ যা সি ++ থেকে আলাদা এবং আপনার নির্দিষ্ট উদাহরণটিকে সি 11-তে সু-সংজ্ঞায়িত করে এমন অভিব্যক্তিগুলি নিয়ন্ত্রণ করার জন্য একটি ব্যতিক্রম সরবরাহ করে


1
"লুপের সমাপ্তি যদি কোনও বস্তুর অবস্থার উপর নির্ভর করে, লুপটি কার্যকর করার জন্য প্রয়োজনীয় সময়টিকে বিবেচনা করা হয় না" তবে এমন কোনও সুরক্ষিত এবং দরকারী অপ্টিমাইজেশন রয়েছে যা বর্তমান ভাষার দ্বারা সহজতর করা হয়েছে saying পর্যবেক্ষণযোগ্য পার্শ্ব-প্রতিক্রিয়া, এমন সময় অসীম হতে গেলেও "। do { x = slowFunctionWithNoSideEffects(x);} while(x != 23);লুপের পরে দেওয়া হোস্টিং কোড যা নির্ভর করে না তার উপর নির্ভর করে না xনিরাপদ এবং যুক্তিসঙ্গত বলে মনে হয় তবে কোনও সংকলককে এই x==23জাতীয় কোড অনুমান করার জন্য এটি দরকারী হিসাবে বেশি বিপজ্জনক বলে মনে হয়।
সুপারক্যাট

47

আমার কাছে, প্রাসঙ্গিক যুক্তিটি হ'ল:

এটি সমাপ্তি প্রমাণিত না হওয়া সত্ত্বেও খালি লুপগুলি অপসারণের মতো সংকলক স্থানান্তরিতকরণের অনুমতি দেওয়ার উদ্দেশ্যে intended

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

সম্পাদনা: বোবা উদাহরণ:

while (complicated_condition()) {
    x = complicated_but_externally_invisible_operation(x);
}
complex_io_operation();
cout << "Results:" << endl;
cout << x << endl;

এখানে, অন্য থ্রেডটি complex_io_operationলুপের মধ্যে সমস্ত জটিল গণনা করার সময় এটি করা দ্রুততর হবে । তবে আপনি যে ধারাটি উদ্ধৃত করেছেন সেগুলি ছাড়াই সংকলকটিকে অপ্টিমাইজেশান তৈরি করার আগে দুটি জিনিস প্রমাণ করতে হবে: 1) complex_io_operation()লুপের ফলাফলের উপর নির্ভর করে না এবং 2) লুপটি সমাপ্ত হবে । 1) প্রমাণ করা বেশ সহজ, প্রমাণিত 2) হ'ল সমস্যাটি। ধারাটির সাথে, এটি লুপটি সমাপ্ত হতে পারে এবং সমান্তরাল জয় পেতে পারে।

আমি আরও কল্পনা করেছি যে ডিজাইনাররা বিবেচনা করেছিলেন যে উত্পাদন কোডে অসীম লুপগুলি দেখা যায় সেগুলি খুব বিরল এবং সাধারণত ইভেন্ট-চালিত লুপগুলির মতো জিনিস যা কোনওভাবে I / O অ্যাক্সেস করে। ফলস্বরূপ, তারা আরও সাধারণ কেসটিকে অপ্টিমাইজ করার পক্ষে বিরল ক্ষেত্রে (অসীম লুপগুলি) অনুমান করেছে (অজানা, তবে যান্ত্রিকভাবে নিরবচ্ছিন্ন প্রমাণ করতে অসুবিধা, লুপ)।

তবে এর অর্থ এই নয় যে শেখার উদাহরণগুলিতে ব্যবহৃত অসীম লুপগুলি ফলস্বরূপ ক্ষতিগ্রস্থ হবে এবং শিক্ষানবিশ কোডে গোটচগুলি উত্থাপন করবে। আমি বলতে পারি না এটি পুরোপুরি ভাল জিনিস।

সম্পাদনা: অন্তর্দৃষ্টিপূর্ণ নিবন্ধের সাথে আপনি এখন সংযুক্ত, আমি বলব যে "সংকলকটি প্রোগ্রাম সম্পর্কে এক্স ধরে নিতে পারে" এটি যদি যৌক্তিকভাবে "যদি প্রোগ্রামটি এক্সকে সন্তুষ্ট না করে, আচরণটি অপরিবর্তিত থাকে" to আমরা এটি নিম্নরূপে এটি প্রদর্শন করতে পারি: মনে করুন যে কোনও প্রোগ্রাম রয়েছে যা সম্পত্তি X পূরণ করে না। এই প্রোগ্রামটির আচরণটি কোথায় সংজ্ঞায়িত হবে? স্ট্যান্ডার্ডটি সম্পত্তি এক্স সত্য হিসাবে ধরে নিয়ে আচরণের সংজ্ঞা দেয়। যদিও স্ট্যান্ডার্ডটি স্পষ্টভাবে আচরণটি অপরিজ্ঞাতভাবে ঘোষণা করে না তবে এটি বাদ দিয়ে এটিকে অপরিজ্ঞাত হিসাবে ঘোষণা করেছে।

অনুরূপ যুক্তি বিবেচনা করুন: "সংকলকটি ধরে নিতে পারে যে ভেরিয়েবল এক্স কেবল সিকোয়েন্স পয়েন্টগুলির মধ্যে একবারে নির্ধারিত হয়" "সিকোয়েন্স পয়েন্টগুলির মধ্যে একাধিকবার এক্স নির্ধারিত হয়" এর সমান হয়।


"প্রমাণ করা 1) বেশ সহজ" - আসলে যোহানেস যে ধারাটির বিষয়ে জিজ্ঞাসা করছে সেটির অধীনে লঘু সমাপ্তি অনুমান করার জন্য সংকলকটির জন্য 3 শর্তগুলি অবিলম্বে অনুসরণ করা যায় না? আমি তাদের পরিমাণ মনে করি, "সম্ভবত চিরকাল ঘুরানো ছাড়া লুপটির কোনও পর্যবেক্ষণযোগ্য প্রভাব নেই" এবং ধারাটি নিশ্চিত করে যে "চিরতরে স্পিনিং" এই জাতীয় লুপগুলির গ্যারান্টিযুক্ত আচরণ নয়।
স্টিভ জেসপ

@ স্টিভ: লুপটি শেষ না হলে এটি সহজ; তবে যদি লুপটি সমাপ্ত হয় তবে এটিতে অযৌক্তিক আচরণ থাকতে পারে যা এর প্রক্রিয়াজাতকরণকে প্রভাবিত করে complex_io_operation
ফিলিপ পটার

ওফস, হ্যাঁ, আমি মিস করেছি যে এটি অ-অস্থির লোকাল / এলিয়াস / আইও অপে ব্যবহৃত যা কিছু পরিবর্তন করতে পারে। সুতরাং আপনি ঠিক বলেছেন: যদিও এটি অগত্যা তা অনুসরণ করে না, এমন অনেকগুলি ক্ষেত্রে রয়েছে যা সংকলকরা প্রমাণ করতে পারে এবং এমন প্রমাণ দেয় যে এ জাতীয় কোনও পরিবর্তন ঘটে না।
স্টিভ জেসপ

"তবে এর অর্থ এই যে, উদাহরণস্বরূপ শেখার জন্য ব্যবহৃত অসীম লুপগুলি ফলস্বরূপ ক্ষতিগ্রস্থ হবে এবং প্রাথমিক কোডে গোটচগুলি উত্থাপন করবে I আমি বলতে পারি না এটি পুরোপুরি ভাল জিনিস" " কেবলমাত্র অপ্টিমাইজেশন বন্ধ দিয়ে সংকলন করুন এবং এটি এখনও কাজ করা উচিত
KitsuneYMG

1
@ সুপের্যাট: আপনি যা বর্ণনা করেছেন তা বাস্তবে যা ঘটবে তা হ'ল, তবে খসড়া মানকটির প্রয়োজন এটি নয়। আমরা ধরে নিতে পারি না যে সংকলকটি জানে না কোনও লুপটি শেষ হবে কিনা। কম্পাইলার যদি না লুপ জানেন বিনষ্ট হবে না, এটা যাই হোক না কেন এটা পছন্দ করতে পারেন। DS9K হবে জন্য অনুনাসিক ভূত তৈরি কোনো কোন ইনপুট / আউটপুট ইত্যাদি অসীম লুপ (অতএব, DS9K সমাধান বিরাম সমস্যা।)
ফিলিপ পটার

15

আমি মনে করি আপনার সম্পাদনা থেকে সঠিক ব্যাখ্যাটি হ'ল: খালি অসীম লুপগুলি নির্ধারিত আচরণ।

আমি এটি বিশেষত স্বজ্ঞাত আচরণ বলব না, তবে এই ব্যাখ্যাটি বিকল্পটির চেয়ে আরও বেশি অর্থবোধ করে যে, সংকলকটি ইউবি-র সাহায্যে অনিয়মিত লুপগুলি উপেক্ষা করার অনুমতি দেয় ar

অসীম loops UB হন, এটি শুধু এর মানে হল যে অ সসীম প্রোগ্রাম অর্থপূর্ণ বিবেচনা করা হয় না: সি ++ 0x অনুযায়ী, তারা আছে কোন শব্দার্থবিদ্যা।

এটি একটি নির্দিষ্ট পরিমাণে অর্থও তৈরি করে। এগুলি একটি বিশেষ কেস, যেখানে বেশিরভাগ পার্শ্ব প্রতিক্রিয়া কেবলমাত্র আর ঘটে না (উদাহরণস্বরূপ, কিছুই কখনই ফিরে আসে না main), এবং সংখ্যক সংকলক অপ্টিমাইজেশানগুলি অসীম লুপগুলি সংরক্ষণ করে বাধা দেয়। উদাহরণস্বরূপ, লুপের ওপারে গণনাগুলি সরানো পুরোপুরি বৈধ যদি লুপটির কোনও পার্শ্ব প্রতিক্রিয়া না থাকে, কারণ শেষ পর্যন্ত, গণনাটি যে কোনও ক্ষেত্রে করা হবে। তবে যদি লুপটি কখনই বন্ধ না হয়, আমরা নিরাপদে এটি জুড়ে কোডটি পুনরায় সাজিয়ে তুলতে পারি না, কারণ প্রোগ্রামটি স্থগিত হওয়ার আগে আমরা সম্ভবত কোন পরিবর্তনগুলি বাস্তবায়িত করব changing আমরা যদি কোনও হ্যাংিং প্রোগ্রামকে ইউবি হিসাবে ব্যবহার না করি তবে তা।


7
"খালি অসীম লুপগুলি কি সংজ্ঞায়িত আচরণ"? অ্যালান টুরিং আলাদা হতে অনুরোধ করবে, তবে কেবল যখন সে তার কবরে কাটছে।
ডোনাল ফেলো

11
@ ডোনাল: আমি কখনও ট্যুরিং মেশিনে এর শব্দার্থক সম্পর্কে কিছু বলিনি। আমরা সি ++ তে কোনও পার্শ্ব প্রতিক্রিয়া ছাড়াই অসীম লুপটির শব্দার্থবিজ্ঞানগুলি নিয়ে আলোচনা করছি । এবং আমি এটি পড়ার সাথে সাথে সি ++ 0 এক্স বলতে বেছে নেওয়া হয়েছে যে এই জাতীয় লুপগুলি অপরিজ্ঞাত are
jalf

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

1
এর অর্থ কি এই যে এম্বেড থাকা ডিভাইসের জন্য সি ++ 0x উপযুক্ত নয়? প্রায় সমস্ত এম্বেড থাকা ডিভাইসগুলি অবসানহীন এবং বড় ফ্যাটের ভিতরে তাদের কাজ করে while(1){...}। এমনকি তারা নিয়মিতভাবে while(1);একটি ওয়াচডগ-সহায়তা পুনরায় সেট করার জন্য ব্যবহার করে।
বনাম

1
@vsz: প্রথম ফর্মটি ভাল। অসীম লুপগুলি যথাযথভাবে সংজ্ঞায়িত করা হয়, যতক্ষণ না তাদের কিছু প্রকার পর্যবেক্ষণযোগ্য আচরণ থাকে। দ্বিতীয় রূপটি জটিল, তবে আমি দুটি খুব সহজ উপায় সম্পর্কে ভাবতে পারি: (1) এম্বেডড ডিভাইসগুলিকে লক্ষ্য করে একটি সংকলক কেবল সেই ক্ষেত্রে কঠোর আচরণের সংজ্ঞা দিতে বেছে নিতে পারে, বা (২) আপনি এমন একটি দেহ তৈরি করেন যা কিছু ডামি লাইব্রেরি ফাংশন বলে calls । সংকলক যতক্ষণ না জানে যে ফাংশনটি কী করে, ততক্ষণ ধরে নিতে হবে এটির কিছুটা পার্শ্ব প্রতিক্রিয়া থাকতে পারে এবং তাই এটি লুপের সাথে গোলযোগ করতে পারে না।
জলফ

8

আমি মনে করি এটি এই ধরণের প্রশ্নের লাইনের সাথে রয়েছে , যা অন্য থ্রেডের উল্লেখ করে । অনুকূলকরণ মাঝেমধ্যে খালি লুপগুলি সরিয়ে ফেলতে পারে।


3
দুর্দান্ত প্রশ্ন। এই অনুচ্ছেদে সেই সংকলকটি তৈরি করতে দেয় এমন লোকটির মতোই সমস্যাটি মনে হচ্ছে। উত্তরের একটিটির সাথে সংযুক্ত আলোচনায় এটি লেখা হয়েছে যে "দুর্ভাগ্যক্রমে, 'অপরিজ্ঞাত আচরণ' শব্দটি ব্যবহার করা হয় নি। তবে মানক যে কোনও সময় 'সংকলক পিটি ধরে নিতে পারে,' তা বোঝানো হয়েছে যে একটি প্রোগ্রাম রয়েছে বৈশিষ্ট্য নন-পি এর শব্দার্থবিজ্ঞান রয়েছে " । এটি আমাকে অবাক করে দেয়। এর অর্থ কি আমার উপরের উদাহরণের প্রোগ্রামটির আচরণ রয়েছে অনির্ধারিত and
জোহানেস স্কাউব -

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

... কম্পাইলার এর যুক্তি একটি স্ববিরোধ অনুমতি প্রোগ্রাম অবশ্যই UB খুব জোরালোভাবে ইঙ্গিত সম্পর্কে, যেহেতু বিশেষ করে এটি কোনো X এর জন্য কম্পাইলার দেয়, অনুমান করতে নিশ্চয় কম্পাইলার অনুমতি থেকে যে প্রোগ্রাম এক্স সমতূল্য অনুমান যে এটা অনুমতি না যে। আমি লেখকের সাথেও একমত, যে ইউবি যদি উদ্দেশ্য করে থাকে তবে এটি স্পষ্ট করে বলা উচিত, এবং যদি এটি উদ্দেশ্য না করে থাকে তবে নির্দিষ্ট পাঠটি ভুল এবং সংশোধন করা উচিত (সম্ভবত বর্ণের সমতুল্য ভাষায়, "সংকলকটি প্রতিস্থাপন করতে পারে কোড সহ লুপ যার কোনও প্রভাব নেই ", আমি নিশ্চিত নই)।
স্টিভ জেসোপ

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

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

8

প্রাসঙ্গিক সমস্যাটি হ'ল এই সংকলকটির কোডটি পুনরায় অর্ডার করার অনুমতি দেওয়া হয়েছে যার পার্শ্ব প্রতিক্রিয়াগুলি বিরোধী নয়। কম্পাইলার অসীম লুপের জন্য নন-টার্মিনেটিং মেশিন কোড তৈরি করলেও মৃত্যুদন্ডের অবাক করার আদেশটি ঘটতে পারে।

আমি বিশ্বাস করি এটি সঠিক পদ্ধতি। ভাষা নির্দিষ্টকরণ কার্যকর করার আদেশ প্রয়োগের উপায়গুলি সংজ্ঞায়িত করে। আপনি যদি এমন একটি অসীম লুপ চান যা চারদিকে পুনরায় অর্ডার করা যায় না তবে এটি লিখুন:

volatile int dummy_side_effect;

while (1) {
    dummy_side_effect = 0;
}

printf("Never prints.\n");

2
@ জোহানেসস্যাচ-লিটব: যদি কোনও লুপ - অন্তহীন বা না - মৃত্যুদন্ড কার্যকর করার সময় কোনও উদ্বায়ী ভেরিয়েবলগুলি পড়তে বা লিখতে না পারে এবং এটি করতে পারে এমন কোনও ফাংশন কল না করে, একটি সংকলক লুপের কোনও অংশ স্থগিত করতে মুক্ত এটিতে গণনা করা কিছু অ্যাক্সেসের প্রথম প্রচেষ্টা। প্রদত্ত unsigned int dummy; while(1){dummy++;} fprintf(stderror,"Hey\r\n"); fprintf(stderror,"Result was %u\r\n",dummy);, প্রথমটি fprintfনির্বাহ করতে পারে, তবে দ্বিতীয়টি করতে পারেনি (সংকলক উভয়ের dummyমধ্যে গণনা সরিয়ে ফেলতে পারে fprintf, তবে এর মানটি মুদ্রণের সাথে অতীতে যায় না)।
সুপারক্যাট

1

আমি মনে করি সমস্যাটি সম্ভবত সর্বোত্তমভাবে বলা যেতে পারে, কারণ "যদি পরবর্তী কোনও কোডের কোডটি কোনও পূর্ববর্তী কোডের উপর নির্ভর না করে এবং কোডের পূর্ববর্তী অংশটি সিস্টেমের অন্য কোনও অংশে কোনও পার্শ্ব-প্রতিক্রিয়া না রাখে, সংকলকটির আউটপুট প্রাক্তনটির মৃত্যুর পূর্বে, পরে বা সংমিশ্রণের পরে কোডটির পরবর্তী অংশটি কার্যকর করতে পারে, যদিও প্রাক্তন কোডটি আসলে বা কখন সম্পূর্ণ হবে কিনা তা বিবেচনা না করে লুপ থাকে তবে উদাহরণস্বরূপ, সংকলকটি আবার লিখতে পারে:

অকার্যকর টেস্টফর্ম্যাট (int এন)
{
  int a = 1, b = 1, c = 1;
  যখন (পাও (এ, এন) + পাউ (বি, এন)! = পাউ (সি, এন))
  {
    যদি (খ> ক) এ ++; অন্যথায় যদি (সি> খ) {এ = 1; খ ++,}; অন্য {এ = 1; খ = 1; C ++};
  }
  printf ("ফলাফল");
  প্রিন্টফ ("% d /% d /% d", ক, খ, সি);
}

যেমন

অকার্যকর টেস্টফর্ম্যাট (int এন)
{
  যদি (কাঁটাচামচ_প্রথম_ত্যাগ ())
  {
    int a = 1, b = 1, c = 1;
    যখন (পাও (এ, এন) + পাউ (বি, এন)! = পাউ (সি, এন))
    {
      যদি (খ> ক) এ ++; অন্যথায় যদি (সি> খ) {এ = 1; খ ++,}; অন্য {এ = 1; খ = 1; C ++};
    }
    signal_other_thread_and_die ();
  }
  অন্যথায় // দ্বিতীয় থ্রেড
  {
    printf ("ফলাফল");
    wait_for_other_thread ();
  }
  প্রিন্টফ ("% d /% d /% d", ক, খ, সি);
}

সাধারণত অযৌক্তিক নয়, যদিও আমি এটি উদ্বিগ্ন হতে পারি:

  int মোট = 0;
  (i = 0; num_reps> i; i ++) এর জন্য
  {
    update_progress_bar (ঝ);
    মোট + + = do_something_slow_with_no_side_effects (ঝ);
  }
  show_result (মোট);

হবে

  int মোট = 0;
  যদি (কাঁটাচামচ_প্রথম_ত্যাগ ())
  {
    (i = 0; num_reps> i; i ++) এর জন্য
      মোট + + = do_something_slow_with_no_side_effects (ঝ);
    signal_other_thread_and_die ();
  }
  আর
  {
    (i = 0; num_reps> i; i ++) এর জন্য
      update_progress_bar (ঝ);
    wait_for_other_thread ();
  }
  show_result (মোট);

একটি সিপিইউ গণনা হ্যান্ডেল করে এবং অন্যটি প্রগতি বার আপডেটগুলি পরিচালনা করে, পুনর্লিখনের দক্ষতা উন্নত হবে। দুর্ভাগ্যক্রমে, এটি অগ্রগতি বারের আপডেটগুলি হওয়া উচিত তার চেয়ে কম কার্যকর করবে।


আমি মনে করি যে আপনার অগ্রগতি বার কেস পৃথক করা যায় নি, কারণ একটি অগ্রগতি বার প্রদর্শন করা একটি লাইব্রেরি I / O কল। অপটিমাইজেশনগুলি এইভাবে দৃশ্যমান আচরণ পরিবর্তন করা উচিত নয়।
ফিলিপ পটার

ফিলিপ পটার: ধীর রুটিনের যদি পার্শ্ব-প্রতিক্রিয়া থাকে তবে তা অবশ্যই সত্য। আমার উদাহরণটিতে আগে এটি অর্থহীন হবে যদি তা না হয়, তাই আমি এটি পরিবর্তন করেছি। আমার অনুমানের ব্যাখ্যাটি হ'ল সিস্টেমটিকে ধীর কোডের কার্যকরকরণ স্থগিত করার মঞ্জুরি দেওয়া হয় যতক্ষণ না এর প্রভাবগুলি (এটি কার্যকর করার সময় ব্যতীত) দৃশ্যমান হয়ে যায়, অর্থাত্ show_result () কল। যদি প্রগতি-বার কোডটি চলমান মোটের ব্যবহার করে বা কমপক্ষে এটি করার ভান করে তবে এটি ধীর কোডের সাথে সিঙ্ক আপ করতে বাধ্য করবে।
সুপারক্যাট

1
এটি সেই সমস্ত অগ্রগতি
বারগুলিকে

0

এটি তুচ্ছ-তুচ্ছ ঘটনাগুলির জন্য সংকলকটির পক্ষে নির্ধারণযোগ্য নয় যদি এটি মোটেই অসীম লুপ হয়।

বিভিন্ন ক্ষেত্রে, এটি ঘটতে পারে যে আপনার অপটিমাইজার আপনার কোডের জন্য আরও ভাল জটিলতায় পৌঁছে যাবে (যেমন এটি ও (এন ^ 2) এবং আপনি অপ্টিমাইজেশনের পরে ও (এন) বা ও (1) পেয়েছেন)।

সুতরাং, এমন নিয়ম অন্তর্ভুক্ত করা যা C ++ স্ট্যান্ডার্ডের মধ্যে অসীম লুপ অপসারণের অনুমতি দেয় না ফলে অনেকগুলি অপটিমাইজেশন অসম্ভব হয়ে যায়। এবং বেশিরভাগ লোকেরা এটি চায় না। আমি মনে করি এটি আপনার প্রশ্নের যথেষ্ট উত্তর দেয়।


আরেকটি জিনিস: আমি এমন কোনও বৈধ উদাহরণ দেখিনি যেখানে আপনাকে অসীম লুপের দরকার হয় যা কিছুই করে না।

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

আপনি যদি এমন কোনও বৈধ / ভাল উদাহরণ জানেন যেখানে আপনাকে অসীম লুপের প্রয়োজন হয় যা কিছুই না করে তবে দয়া করে আমাকে বলুন।


1
আপনি যেখানে অসীম লুপটি পেতে চান তার উদাহরণ: একটি এম্বেড থাকা সিস্টেম যেখানে আপনি কার্য সম্পাদনের কারণে ঘুমাতে চান না এবং সমস্ত কোড একটি বাধা বা দুটি বন্ধ করে দিচ্ছে?
জেসিএক্স

স্ট্যান্ডার্ড সি-তে জে.এক্স.এক্স.আর.পি.এস. বাধাগুলি একটি পতাকা নির্ধারণ করবে যা মূল লুপটি যাচাই করে, তাই পতাকাগুলি সেট হওয়ার ক্ষেত্রে প্রধান লুপটি পর্যবেক্ষণযোগ্য আচরণ করতে পারে। বিঘ্নগুলিতে যথেষ্ট কোড চালানো অ পোর্টেবল is
এমএম

-1

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

আমি অন্য কথায়, আপনার গ্লোবালগুলিকে অস্থির করে তুলুন - পাশাপাশি যুক্তিগুলি পয়েন্টার / রেফারেন্সের মাধ্যমে এ জাতীয় লুপে গেছে।


যদি তারা অন্য থ্রেডের সাথে ইন্টারঅ্যাক্ট করে থাকে তবে আপনার এগুলিকে অস্থিতিশীল করা উচিত নয়, তাদের পরমাণু তৈরি করা উচিত নয় বা লক দিয়ে তাদের সুরক্ষা দেওয়া উচিত নয়।
বিসোয়েটস

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