অপ্টিমাইজেশন স্তর -O3 জি ++ মধ্যে বিপজ্জনক?


232

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

এটি কি সত্য, এবং যদি তাই হয় তবে কেন? আমার কি শুধু আঁকড়ে থাকা উচিত -O2?


38
এটি কেবলমাত্র বিপজ্জনক যদি আপনি অপরিজ্ঞাত আচরণের উপর নির্ভর করে থাকেন। এবং তারপরেও আমি অবাক হব যদি এটি অপ্টিমাইজেশনের স্তরটি ছিল যা কিছু গোলমেলে ফেলেছিল।
শেঠ কার্নেগি 16

5
সংকলক এখনও এমন একটি প্রোগ্রাম তৈরি করতে সীমাবদ্ধ যা এটি "কোডটি" যেমন আপনার কোডটি ঠিকঠাক করে তোলে beha আমি জানি না যে -O3বিশেষভাবে বগী হিসাবে বিবেচিত হয়? আমি মনে করি এটি সম্ভবত সংজ্ঞায়িত আচরণকে "খারাপ" করে তুলতে পারে কারণ এটি কিছু অনুমানের ভিত্তিতে অদ্ভুত এবং দুর্দান্ত কাজ করতে পারে তবে এটি আপনার নিজের দোষ হবে। তাই সাধারণত, আমি বলব এটি ঠিক আছে।
BoBTFish

5
এটি সত্য যে উচ্চতর অপ্টিমাইজেশনের স্তরগুলি বাগ সংকলকগুলির চেয়ে বেশি প্রবণ। আমি নিজে বেশ কয়েকটি কেস আঘাত করেছি, তবে সাধারণভাবে সেগুলি এখনও বিরল।
রহস্যময়

21
-O2চালু হয় -fstrict-aliasingএবং যদি আপনার কোডটি এটি থেকে যায় তবে এটি সম্ভবত অন্যান্য অপ্টিমাইজেশান থেকে বেঁচে থাকবে, যেহেতু এটি এমন একটি যা মানুষ বার বার ভুল হয়ে যায়। তাই বলা হয়, -fpredictive-commoningশুধুমাত্র হয় -O3, এবং যে সক্রিয় সম্পাতবিন্দু নিয়ে ভুল অনুমানের দ্বারা সৃষ্ট আপনার কোডে বাগ সক্রিয় হতে পারে। আপনার কোডটি যত কম ভুল হবে তত কম বিপজ্জনক অপটিমাইজেশনটি ;-)
স্টিভ জেসোপ

6
@ প্লাজমাএইচএইচ, আমি মনে করি না "স্ট্রিক্টর" এর একটি ভাল বর্ণনা -Ofast, উদাহরণস্বরূপ এটি এনএএন-এর আইইইই-সম্মতিজনক হ্যান্ডলিং বন্ধ করে দেয়
জোনাথন ওয়েকেলি

উত্তর:


223

জিসিসির প্রথম দিনগুলিতে (২.৮ ইত্যাদি) এবং এএসসিএসের সময়ে, এবং রেডহাট ২.৯6 -ও ৩ কখনও কখনও বেশ বাগি ছিল। তবে এটি এক দশক আগের, এবং -O3 অন্যান্য স্তরের অপ্টিমাইজেশনের চেয়ে খুব বেশি আলাদা নয় (বগিটে)।

তবে এটি নিয়মগুলির উপর আরও কঠোরভাবে নির্ভর করার কারণে এবং বিশেষত কোণার কেসগুলি ভাষা (গুলি) এর ক্ষেত্রে লোকেরা অপরিজ্ঞাত আচরণের উপর নির্ভর করে এমন কেসগুলি প্রকাশ করে।

একটি ব্যক্তিগত নোট হিসাবে, আমি এখন -O3 দিয়ে বহু বছর ধরে আর্থিক খাতে প্রোডাকশন সফটওয়্যারটি চালাচ্ছি এবং এখনও আমি এমন কোনও বাগের মুখোমুখি হইনি যা আমি -O2 ব্যবহার করতে পারতাম না তবে সেখানে থাকত না।

জনপ্রিয় চাহিদা অনুসারে, এখানে একটি সংযোজন:

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

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

ওটো মনে হচ্ছে -অফেষ্ট ব্যবহার করার সময় অবশ্যই যত্ন নেওয়া উচিত, যা বলে:

-অলফিট সমস্ত -O3 অনুকূলিতকরণ সক্ষম করে। এটি এমন সমস্ত অপ্টিমাইজেশন সক্ষম করে যা সমস্ত স্ট্যান্ডার্ড অনুগত প্রোগ্রামগুলির জন্য বৈধ নয়।

যা আমাকে এই উপসংহারে পৌঁছে দেয় যে -O3 পুরোপুরি মানের সাথে সম্মতিযুক্ত হ'ল।


2
আমি ঠিক বিপরীত কিছু ব্যবহার। আমি সর্বদা -Os বা -O2 (কখনও কখনও ও 2 একটি ছোট এক্সিকিউটেবল জেনারেট করে) ব্যবহার করি .. .. প্রোফাইল দেওয়ার পরে আমি কোডের অংশগুলিতে O3 ব্যবহার করি যা আরও কার্যকর করার সময় নেয় এবং এটি একা 20% পর্যন্ত আরও গতি দিতে পারে।
কফডেভলবার

3
আমি তা গতির জন্য করি O3 বেশিরভাগ সময় জিনিসগুলিকে ধীর করে তোলে। ঠিক কেন জানি না, আমি সন্দেহ করি এটি নির্দেশের ক্যাশেটিকে দূষিত করে।
কফডেভলপার

4
@ ডারিওইউ আমার কাছে অনুরোধ করা "কোড ব্লাট" করা জনপ্রিয় জিনিস বলে মনে হয় তবে আমি প্রায় কখনও এটিকে মাপদণ্ডের সাথে সমর্থন করি না। এটি আর্কিটেকচারের উপর অনেকটাই নির্ভর করে তবে প্রতিবার প্রকাশিত বেঞ্চমার্কগুলি দেখতে (যেমন ফোরিণিক্স.com/… ) এটি দেখায় যে বিশাল পরিমাণে ক্ষেত্রে O3 দ্রুত হচ্ছে। কোড ব্লাট আসলে একটি সমস্যা ছিল তা প্রমাণ করার জন্য প্রয়োজনীয় প্রোফাইলিং এবং সাবধানী বিশ্লেষণ দেখেছি এবং এটি সাধারণত কেবলমাত্র এমন ব্যক্তিদের ক্ষেত্রে ঘটে যা চূড়ান্ত উপায়ে টেম্পলেটগুলি আলিঙ্গন করে।
নীড় ফ্রিডম্যান

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

1
@ প্লাজমাএইচএইচ: ব্যবহার-সেমিওভ সমস্যাটি সাধারণ ক্ষেত্রে সমাধান করা শক্ত হবে। সাধারণত আপনি কেবল আপনার ডেটা বাছাই করেন নি , তাই যখন জিসিসি যখন কোনও শাখা অনুমানযোগ্য কিনা তা সিদ্ধান্ত নেওয়ার চেষ্টা করছে তখন স্থির বিশ্লেষণ std::sortফাংশনগুলিতে কলগুলি সন্ধানের ক্ষেত্রে সাহায্যের সম্ভাবনা কম। স্ট্যাকওভারফ্লো / প্রশ্নগুলি ১০০৯7১০/২০ এর মতো কিছু ব্যবহার করা সাহায্য করবে বা বাছাই করা নেসের সুবিধা নেওয়ার জন্য উত্সটি লিখুন: আপনি> = 128 না হওয়া পর্যন্ত স্ক্যান করুন, তারপরে যোগফল শুরু করুন। স্ফীতিত কোড হিসাবে, হ্যাঁ আমি এটির প্রতিবেদন করার চেষ্টা করি। : পি
পিটার কর্ডেস

42

আমার কিছুটা পরীক্ষিত অভিজ্ঞতায়, -O3পুরো প্রোগ্রামে প্রয়োগ করা প্রায়শই সর্বদা এটি ধীর করে দেয় (তুলনামূলক -O2), কারণ এটি আক্রমণাত্মক লুপটি অনিয়ন্ত্রিত এবং ইনলাইনিং চালু করে যা প্রোগ্রামটি আর নির্দেশের ক্যাশে ফিট করে না। বৃহত্তর প্রোগ্রামগুলির জন্য, এটি -O2তুলনামূলকভাবে সত্যও হতে পারে -Os!

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


10
"প্রায় সবসময়"? এটি "50-50" করুন এবং আমাদের সাথে একটি চুক্তি হবে ;-)।
নো-বাগস হরে

12

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


3
আমি বুঝতে পারি যে কিছু "আপাত অপ্টিমাইজেশন" কোনও প্রোগ্রামকে ধীর করে দিতে পারে তবে আপনি কি এমন একটি উত্স পেয়েছেন যে দাবি করে যে জিসিসি -O3 একটি প্রোগ্রামকে ধীর করেছে?
হাঁস 14

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

@ প্লাজমাএইচএইচ: আসলে, একটি ছোট ক্যাশে আকার এমন একটি বিষয় যা সংকলক খুব ভাল পয়েন্ট করতে পারে। এটি সত্যিই একটি ভাল উদাহরণ। দয়া করে উত্তরে রাখুন।
21:32

1
@ প্লাজমাএইচএইচ পেন্টিয়াম তৃতীয়টিতে 16 কেবি কোড ক্যাশে ছিল। এএমডি এর কে 6 এবং তারপরে আসলে 32KB নির্দেশের ক্যাশে ছিল। পি 4 এর প্রায় 96KB মূল্য দিয়ে শুরু হয়েছিল। কোর আই 7 এর আসলে একটি 32KB এল 1 কোড ক্যাশে রয়েছে। নির্দেশের ডিকোডারগুলি আজকাল শক্তিশালী, সুতরাং আপনার এল 3 প্রায় কোনও লুপের জন্য পিছনে পড়া যথেষ্ট ভাল।
doug65536

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

8

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

এটি এইভাবে ভাবুন: O3 O2 এর শীর্ষে আরও রূপান্তরগুলি যুক্ত করে, যা O1 এর শীর্ষে আরও ট্রান্সফর্মেশন যুক্ত করে। পরিসংখ্যানগতভাবে বলতে গেলে, আরও রূপান্তরগুলির অর্থ আরও বেশি বাগ। যে কোনও সংকলকের ক্ষেত্রে এটি সত্য।


3

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

unsigned int * pciMemory;
askDriverForMapping( & pciMemory );
...
pciMemory[ 0 ] = someCommandIdx;
pciMemory[ 0 ] = someCommandLength;
for ( int i = 0; i < sizeof( someCommand ); i++ )
    pciMemory[ 0 ] = someCommand[ i ];

কার্ড প্রত্যাশার মতো কাজ করে নি। আমি যখন সমাবেশ দেখেছি আমি বুঝলাম যে কম্পাইলার শুধুমাত্র লিখেছিলেন someCommand[ the last ]মধ্যে pciMemory, সমস্ত পূর্ববর্তী লিখেছেন বাদ।

উপসংহারে: অপ্টিমাইজেশনের সাথে সঠিক এবং মনোযোগী হন।


38
তবে এখানে মুল বক্তব্যটি হ'ল আপনার প্রোগ্রামটি কেবল অনির্ধারিত আচরণ করেছে; অপ্টিমাইজার কিছুই ভুল করেনি। বিশেষত আপনার pciMemoryহিসাবে ঘোষণা করা প্রয়োজন volatile
কনরাড রুডল্ফ

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

4
আমি এটি স্ট্যান্ডার্ডে পেয়েছি (10+ বছর পরে)) - একটি অস্থির ঘোষণার সাহায্যে মেমরি-ম্যাপযুক্ত ইনপুট / আউটপুট পোর্টের সাথে সম্পর্কিত কোনও বস্তু বা অ্যাসিঙ্ক্রোনসিয়াল বিঘ্ন ঘটানো ফাংশন দ্বারা অ্যাক্সেস করা কোনও বস্তু বর্ণনা করতে ব্যবহার করা যেতে পারে। ঘোষিত বস্তুর উপর ক্রিয়াগুলি কোনও প্রয়োগ দ্বারা '' অনুকূলিতকরণ '' বা অভিব্যক্তির মূল্যায়নের নিয়মের অনুমতি ব্যতীত পুনরায় সাজানো হবে না।
বরিসবিএন

2
@Borisbn কিছুটা অফ-টপিক কিন্তু আপনি কীভাবে জানবেন যে কোনও নতুন কমান্ড প্রেরণের আগে আপনার ডিভাইস কমান্ড নিয়েছে?
ব্যবহারকারীর 877329

3
@ ব্যবহারকারী 73৩73৩29২ আমি এটি ডিভাইসের আচরণের দ্বারা দেখেছি তবে এটি একটি দুর্দান্ত অনুসন্ধান ছিল
বরিসবিএন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.