কোডিং অনুশীলনগুলি যা সংকলক / অপ্টিমাইজারটিকে একটি দ্রুত প্রোগ্রাম তৈরি করতে সক্ষম করে


116

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

সময়ের সাথে সাথে সংকলকগুলি পরিপক্ব হয়। তারা খুব স্মার্ট হয়ে ওঠে যে তাদের প্রবাহ বিশ্লেষণগুলি আপনাকে সম্ভবত যতটা করতে পারে তার চেয়ে নিবন্ধগুলিতে কী মান রাখতে হবে সে সম্পর্কে তাদের আরও ভাল সিদ্ধান্ত নিতে দেয়। নিবন্ধের কীওয়ার্ডটি গুরুত্বহীন হয়ে উঠেছে।

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

কোন কোডিং অনুশীলনগুলি উপলব্ধ যা সংকলক / অপ্টিমাইজারটিকে দ্রুত কোড উত্পন্ন করতে সক্ষম করতে পারে?

  • আপনার ব্যবহৃত প্ল্যাটফর্ম এবং সংকলক সনাক্তকরণ প্রশংসিত হবে।
  • কেন কৌশলটি কাজ করে বলে মনে হচ্ছে?
  • নমুনা কোড উত্সাহিত করা হয়।

এখানে একটি সম্পর্কিত প্রশ্ন

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

[সম্পাদনা] সম্পর্কিত লিঙ্কটি অফসেট করুন


7
সম্প্রদায়ের উইকি ইমোর পক্ষে একজন ভাল প্রার্থী হতে পারেন যেহেতু এই (আকর্ষণীয়) প্রশ্নের কোনও 'একক' নির্দিষ্ট উত্তর নেই ...
ক্রিস্টোফেড

আমি প্রতিবার এটি মিস করি। এটি নির্দেশ করার জন্য আপনাকে ধন্যবাদ।
এভিলটিচ

'আরও ভাল' বলতে কী বোঝায় আপনি কেবল 'দ্রুত' বা আপনার কাছে অন্যান্য শ্রেষ্ঠত্বের মানদণ্ড রয়েছে?
হাই পারফরম্যান্স মার্ক

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

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

উত্তর:


54

স্থানীয় ভেরিয়েবলগুলিতে লিখুন আউটপুট আর্গুমেন্টগুলি নয়! এলোমেলো মন্দা ঘটার জন্য এটি একটি বিশাল সহায়তা হতে পারে। উদাহরণস্বরূপ, যদি আপনার কোডটি মনে হয়

void DoSomething(const Foo& foo1, const Foo* foo2, int numFoo, Foo& barOut)
{
    for (int i=0; i<numFoo, i++)
    {
         barOut.munge(foo1, foo2[i]);
    }
}

সংকলকটি foo1 জানে না! = বারআউট এবং সুতরাং প্রতিটি সময় লুপের মাধ্যমে foo1 পুনরায় লোড করতে হবে। বারআউটে লেখা শেষ না হওয়া পর্যন্ত এটি foo2 [i] পড়তে পারে না। আপনি সীমাবদ্ধ পয়েন্টারগুলির সাথে জগাখিচুড়ি শুরু করতে পারেন, তবে এটি করার মতো এটি কার্যকর (এবং আরও পরিষ্কার):

void DoSomethingFaster(const Foo& foo1, const Foo* foo2, int numFoo, Foo& barOut)
{
    Foo barTemp = barOut;
    for (int i=0; i<numFoo, i++)
    {
         barTemp.munge(foo1, foo2[i]);
    }
    barOut = barTemp;
}

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


7
প্রোগ্রামারদের জন্য প্রায়শই জিনিসগুলি পড়ার / বুঝতে সহজতর করার এটির অতিরিক্ত উপকার রয়েছে কারণ যেহেতু তাদের সম্ভাব্য অ-সুস্পষ্ট পার্শ্ব প্রতিক্রিয়া সম্পর্কেও চিন্তা করতে হবে না।
মাইকেল বুড়

বেশিরভাগ IDE গুলি ডিফল্টরূপে স্থানীয় ভেরিয়েবলগুলি প্রদর্শন করে, তাই এখানে টাইপিং কম হয়
এভিল টিচ

9
সীমাবদ্ধ পয়েন্টারগুলি ব্যবহার করে আপনি সেই অপ্টিমাইজেশনটি সক্ষম করতে পারেন
বেন ভয়েগট

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

আপনার কাছে ঠিক আশা করা গেছে যে ফু এর একটি অনুলিপি অপারেশন সংজ্ঞায়িত করা হয়নি যা কয়েক
মেগা

76

সংকলকটিকে দ্রুত কোড তৈরি করতে সহায়তা করার জন্য এখানে একটি কোডিং অনুশীলন — যে কোনও ভাষা, কোনও প্ল্যাটফর্ম, যে কোনও সংকলক, যে কোনও সমস্যা:

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

এরপরে, আপনার কোডটি প্রোফাইল করুন।

তারপরে এবং কেবল তখনই, আপনি কীভাবে মেমরি ব্যবহার করবেন তা সংকলককে বলার প্রভাবগুলি তদন্ত শুরু করতে চাইতে পারেন। একবারে 1 পরিবর্তন করুন এবং এর প্রভাব পরিমাপ করুন।

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


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

22
& অন্যান্য% বেশিরভাগ সস্তা-মুক্ত-বিনামূল্যে পাটিগণিত কৌশলগুলির সাথে প্রায় সবসময়ই অনুকূলিত হয়। যা অপ্টিমাইজড হয় না তা হ'ল ডান হাতের ক্রমটি একটি ভেরিয়েবল যা কেবল সর্বদা দু'জনের শক্তি হওয়ার জন্য ঘটে।
পোটোসওয়টার

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

17
দু'জনের ধ্রুবক পাওয়ার জন্য n, জিসিসি অপ্টিমাইজেশন অক্ষম থাকলেও প্রতিস্থাপন % nকরে । এটি & (n-1)
হ'ল

12
নেতিবাচক পূর্ণসংখ্যা বিভাগের জন্য সি এর বুদ্ধিমান নিয়মের কারণে (0 টির দিকে গোল হয় এবং সর্বদা ধনাত্মক অবশিষ্ট থাকে না বরং নেতিবাচক অবশিষ্ট থাকে) এর ফলে % টাইপ হিসাবে স্বাক্ষরিত হতে পারে না as এবং বেশিরভাগ সময়, অজ্ঞান কোডাররা স্বাক্ষরিত ধরণগুলি ব্যবহার করে ...
আর .. গিটিহাব

47

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

#define N 1000000;
int matrix[N][N] = { ... };

//awesomely fast
long sum = 0;
for(int i = 0; i < N; i++){
  for(int j = 0; j < N; j++){
    sum += matrix[i][j];
  }
}

//painfully slow
long sum = 0;
for(int i = 0; i < N; i++){
  for(int j = 0; j < N; j++){
    sum += matrix[j][i];
  }
}

কড়া কথা বলতে এটি কোনও অপ্টিমাইজার সমস্যা নয়, তবে এটি একটি অপটিমাইজেশন সমস্যা issue
এভিলটিচ

10
নিশ্চিত এটি একটি অপ্টিমাইজার সমস্যা কয়েক দশক ধরে লোকেরা স্বয়ংক্রিয় লুপ ইন্টারচেঞ্জ অপ্টিমাইজেশন সম্পর্কে কাগজপত্র লিখছে।
ফিল মিলার

20
@ পোটাটোসওয়টার আপনি কী সম্পর্কে কথা বলছেন? সি সংকলক একই চূড়ান্ত ফলাফলটি যতক্ষণ না পর্যবেক্ষণ করতে পারে তা করতে পারে এবং জিসিসি ৪.৪ রয়েছে -floop-interchangeযা অপ্টিমাইজারটি লাভজনক বলে মনে করলে এটি একটি অভ্যন্তরীণ এবং বাহ্যিক লুপটি ফ্লিপ করবে।
মোহাম্মদ

2
হু, ঠিক আছে আপনি সেখানে যান। সি শব্দার্থবিজ্ঞান প্রায়শই এলিয়াসিং ইস্যু দ্বারা বিদ্রূপিত হয়। আমার ধারণা এখানে আসল পরামর্শটি সেই পতাকাটি পাস করা!
পোটোসওয়টার

36

জেনেরিক অপটিমাইজেশন

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

ছোট ক্রিয়াকলাপগুলি inlineম্যাক্রো হিসাবে ঘোষণা করুন

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

মৃত এবং অপ্রয়োজনীয় কোড সরান

যদি কোডটি ব্যবহার না করা হয় বা প্রোগ্রামের ফলাফলে অবদান না দেয় তবে এ থেকে মুক্তি পান।

অ্যালগরিদমের নকশা সরল করুন

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

লুপ আনরোলিং

প্রতিটি লুপের ইনক্রিমেন্টিং এবং টার্মিনেশন চেকিংয়ের ওভারহেড থাকে। পারফরম্যান্স ফ্যাক্টরের একটি অনুমান পেতে, ওভারহেডে নির্দেশিকাগুলির সংখ্যা গণনা করুন (ন্যূনতম 3: বর্ধন, চেক, লুপের সূচনা) এবং লুপের ভিতরে বিবৃতি সংখ্যার দ্বারা ভাগ করুন divide ভাল নম্বর কম।

সম্পাদনা করুন: এর আগে লুপ আন্রোলিংয়ের একটি উদাহরণ সরবরাহ করুন:

unsigned int sum = 0;
for (size_t i; i < BYTES_TO_CHECKSUM; ++i)
{
    sum += *buffer++;
}

তালিকাভুক্তির পরে:

unsigned int sum = 0;
size_t i = 0;
**const size_t STATEMENTS_PER_LOOP = 8;**
for (i = 0; i < BYTES_TO_CHECKSUM; **i = i / STATEMENTS_PER_LOOP**)
{
    sum += *buffer++; // 1
    sum += *buffer++; // 2
    sum += *buffer++; // 3
    sum += *buffer++; // 4
    sum += *buffer++; // 5
    sum += *buffer++; // 6
    sum += *buffer++; // 7
    sum += *buffer++; // 8
}
// Handle the remainder:
for (; i < BYTES_TO_CHECKSUM; ++i)
{
    sum += *buffer++;
}

এই সুবিধাটিতে, একটি গৌণ সুবিধা পাওয়া যায়: প্রসেসরের নির্দেশের ক্যাশে পুনরায় লোড করার আগে আরও বিবৃতি কার্যকর করা হয়।

আমি 32 টি স্টেটমেন্টে একটি লুপ আনরোলড করেছিলাম তখন আমি বিস্ময়কর ফলাফল পেয়েছি। প্রোগ্রামটি একটি 2 জিবি ফাইলের জন্য একটি চেকসাম গণনা করার পরে এটি একটি অন্তরায়। এই অপ্টিমাইজেশনটি 1 ঘন্টা থেকে 5 মিনিটের মধ্যে ব্লক রিডিং উন্নত পারফরম্যান্সের সাথে মিলিত হয়। লুপ আনরোলিং সমাবেশের ভাষায়ও দুর্দান্ত পারফরম্যান্স সরবরাহ করেছিল, আমার সংকলকটির থেকে memcpyঅনেক দ্রুত ছিল memcpy। - টিএম

ifবিবৃতি হ্রাস

প্রসেসরগুলি শাখাগুলি ঘৃণা করে, বা লাফ দেয়, যেহেতু এটি প্রসেসরকে তার নির্দেশাবলীর সারিটি পুনরায় লোড করতে বাধ্য করে।

বুলিয়ান পাটিগণিত ( সম্পাদিত: কোড টুকরাটিতে কোড বিন্যাস প্রয়োগ, উদাহরণ যুক্ত)

ifবুলিয়ান অ্যাসাইনমেন্টগুলিতে বিবৃতি রূপান্তর করুন । কিছু প্রসেসর শর্তযুক্তভাবে শাখা ছাড়াই নির্দেশাবলী কার্যকর করতে পারে:

bool status = true;
status = status && /* first test */;
status = status && /* second test */;

সংক্ষিপ্ত circuiting এর লজিক্যাল এবং অপারেটর ( &&) পরীক্ষা মৃত্যুদন্ড যদি বাধা দেয় statusহয় false

উদাহরণ:

struct Reader_Interface
{
  virtual bool  write(unsigned int value) = 0;
};

struct Rectangle
{
  unsigned int origin_x;
  unsigned int origin_y;
  unsigned int height;
  unsigned int width;

  bool  write(Reader_Interface * p_reader)
  {
    bool status = false;
    if (p_reader)
    {
       status = p_reader->write(origin_x);
       status = status && p_reader->write(origin_y);
       status = status && p_reader->write(height);
       status = status && p_reader->write(width);
    }
    return status;
};

লুপগুলির বাইরে ফ্যাক্টর ভেরিয়েবল বরাদ্দ

যদি লুপের অভ্যন্তরে ফ্লাইতে কোনও পরিবর্তনশীল তৈরি করা হয় তবে তৈরি / বরাদ্দটি লুপের আগে নিয়ে যান। বেশিরভাগ ক্ষেত্রে, প্রতিটি পুনরাবৃত্তির সময় চলকটি বরাদ্দ করার প্রয়োজন হয় না।

লুপগুলির বাইরে ফ্যাক্টর ধ্রুবক প্রকাশ

যদি কোনও গণনা বা পরিবর্তনশীল মান লুপ সূচকের উপর নির্ভর করে না, এটি লুপের বাইরে (আগে) সরিয়ে ফেলুন।

ব্লকগুলিতে I / O

বড় অংশগুলিতে (ব্লক) ডেটা পড়ুন এবং লিখুন। বৃহত্তর আরও ভাল। উদাহরণস্বরূপ, একবারে একটি অক্টেক্ট পড়া একটি পড়ার সাথে 1024 অক্টেট পড়ার চেয়ে কম দক্ষ।
উদাহরণ:

static const char  Menu_Text[] = "\n"
    "1) Print\n"
    "2) Insert new customer\n"
    "3) Destroy\n"
    "4) Launch Nasal Demons\n"
    "Enter selection:  ";
static const size_t Menu_Text_Length = sizeof(Menu_Text) - sizeof('\0');
//...
std::cout.write(Menu_Text, Menu_Text_Length);

এই কৌশলটির দক্ষতা চাক্ষুষভাবে প্রদর্শিত হতে পারে। :-)

ধ্রুবক ডেটার জন্য printf পরিবার ব্যবহার করবেন না

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

স্মৃতিতে ফর্ম্যাট করুন, তারপরে লিখুন

charএকাধিক ব্যবহার করে একটি অ্যারে ফর্ম্যাট করুন sprintf, তারপরে ব্যবহার করুন fwrite। এটি ডেটা বিন্যাসকে "ধ্রুবক বিভাগ" এবং পরিবর্তনশীল বিভাগগুলিতে বিভক্ত করতে দেয়। চিন্তা করুন মেইল মার্জ

ধ্রুবক পাঠ্য (স্ট্রিং লিটারাল) হিসাবে ঘোষণা করুন static const

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

শেষ অবধি, সংকলকের মতো কোডটি হবে

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


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

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

3
আমি একবার লুপ রোল করে একটি উল্লেখযোগ্য পারফরম্যান্সের উন্নতি পেয়েছি। তারপরে আমি বুঝতে পারলাম কীভাবে কিছুটা দিকনির্দেশ ব্যবহার করে আরও শক্ত করে এটি রোল করা যায়, এবং প্রোগ্রামটি লক্ষণীয়ভাবে দ্রুততর হয়ে উঠল। (প্রোফাইলিং এই নির্দিষ্ট ফাংশনটি রানটাইমের 60-80% হিসাবে দেখিয়েছিল এবং আমি আগে এবং পরে সাবধানতার সাথে পারফরম্যান্স পরীক্ষা করেছিলাম)) আমি বিশ্বাস করি উন্নতি ভাল লোকালটির কারণে হয়েছিল, তবে আমি সে সম্পর্কে পুরোপুরি নিশ্চিত নই।
ডেভিড থর্নলি

16
এর মধ্যে অনেকগুলি প্রোগ্রামার অপ্টিমাইজেশনে সংকলককে সহায়তা করার উপায়গুলির চেয়ে প্রোগ্রামার অপ্টিমাইজেশান। যা মূল প্রশ্নের জোর was উদাহরণস্বরূপ, লুপ আন্রোলিং। হ্যাঁ, আপনি নিজেরাই আনرولিং করতে পারেন, তবে আমার মনে হয় যে এই সংকলকটিতে আপনার জন্য কী কী রোড ব্লক রয়েছে এবং এটি অপসারণ করা আরও কী আকর্ষণীয়।
অ্যাড্রিয়ান ম্যাকার্থি

26

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

এটি বলেছিল, আপনার অন্য ফাইলের একটি ফাইল থেকে একটি ছোট ফাংশনটি অভ্যন্তরীণ লুপ করা উচিত নয়, কারণ এটি এটিকে অন্তর্ভুক্ত হওয়া থেকে বিরত করে।

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

যা পরবর্তী বিন্দুতে নিয়ে যায়, manual # $ @ ম্যানুয়ালটি পড়ুন ! আপনি যদি __restrict__এখানে কোনও এবং একটি ছিটান তবে জিসিসি সরল সি কোডটিকে ভেক্টরাইজ করতে পারে __attribute__( __aligned__ )। আপনি যদি অপ্টিমাইজারের কাছ থেকে খুব নির্দিষ্ট কিছু চান তবে আপনার সুনির্দিষ্ট হতে পারে।


14
এটি একটি উত্তরের উত্তর, তবে নোট করুন যে পুরো প্রোগ্রামের অপটিমাইজেশন আরও জনপ্রিয় হয়ে উঠছে, এবং আসলে অনুবাদ ইউনিটগুলিতে ইনলাইন ফাংশনগুলি করতে পারে।
ফিল মিলার

1
হাঁ @Novelocrat - বলা বাহুল্য আমি খুব কাছ থেকে প্রথমবার আমি দেখেছি কিছু বিস্মিত A.cঢোকা inlined B.c
জনাথন রাইনহার্ট

18

বেশিরভাগ আধুনিক প্রসেসরের উপর, বৃহত্তম বাধা হ'ল মেমরি।

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

ক্যাশে-মিস: আপনি কীভাবে সংকলকটিকে বেশিরভাগ অ্যালগরিদমিকের সাহায্য করতে পারেন তা সত্যিই নিশ্চিত নন, তবে স্মৃতিতে প্রেফেক করার জন্য অন্তর্নিবেশ রয়েছে।

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


4
লোড-হিট-স্টোর এবং বিভিন্ন রেজিস্টার ধরণের জন্য +1। X86 এ এটি কতটা বড় চুক্তিতে রয়েছে তা আমি নিশ্চিত নই, তবে তারা পাওয়ারপিসিতে (উদাহরণস্বরূপ Xbox360 এবং প্লেস্টেশন 3) বিকাশ করছে।
celion

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

11

লোকেরা যে সংখ্যাগরিষ্ঠ কোড লিখবে তা হবে I / O আবদ্ধ (আমি বিশ্বাস করি যে আমি গত 30 বছরে অর্থের জন্য লিখেছি সমস্ত কোড এতটা আবদ্ধ হয়েছে), তাই বেশিরভাগ লোকদের জন্য আশাবাদীর ক্রিয়াকলাপগুলি একাডেমিক হবে be

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


7
আমি অদ্ভুত বলে স্বীকার করি - আমি বড় বৈজ্ঞানিক নম্বর-ক্রাঞ্চিং কোডগুলিতে কাজ করি যা মেমরি-ব্যান্ডউইথের সীমাবদ্ধ। প্রোগ্রামগুলির সাধারণ জনগণের জন্য আমি নীলের সাথে একমত।
উচ্চ পারফরম্যান্স মার্ক

6
সত্য; তবে আজকাল আই / ও-বাউন্ড কোডের একটি ভয়ঙ্কর অনেকগুলি ভাষাগুলিতে লেখা হয় যা ব্যবহারিকভাবে হতাশাব্যঞ্জক languages ​​এমন ভাষাগুলিতেও যেগুলি সংকলকও নেই । আমার সন্দেহ হয় যে সি এবং সি ++ এখনও ব্যবহৃত হয় সে অঞ্চলগুলিতে এমন কিছু অঞ্চলে ঝোঁক থাকবে যেখানে
কোনও কিছুর

3
আমি গত 30 বছরের বেশিরভাগ সময় খুব কম আই / ও দিয়ে কোড নিয়ে কাজ করেছি। 2 বছর ডাটাবেস করার জন্য সংরক্ষণ করুন। গ্রাফিক্স, নিয়ন্ত্রণ ব্যবস্থা, সিমুলেশন - এর কোনওোটাই I / O আবদ্ধ নয়। যদি I / O বেশিরভাগ লোকের বাধা ছিল তবে আমরা ইন্টেল এবং এএমডি তেমন মনোযোগ দেব না।
phkahler

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

3
আমি সম্প্রতি আবিষ্কার করেছি যে সি ++ ভাষায় লিখিত প্রায় কোনও কোডই I / O সীমাবদ্ধ নয়। অবশ্যই, আপনি যদি বাল্ক ডিস্ক স্থানান্তরের জন্য কোনও ওএস ফাংশনটি কল করে থাকেন তবে আপনার থ্রেডটি আই / ও ওয়েটে যেতে পারে (তবে ক্যাশে সহ, এমনকি এটি সন্দেহজনক)। তবে সাধারণ আই / ও লাইব্রেরি ফাংশন, যাঁরা সবাই সুপারিশ করেন কারণ তারা স্ট্যান্ডার্ড এবং পোর্টেবল, তারা আধুনিক ডিস্ক প্রযুক্তির তুলনায় খুব খারাপ ধীরে ধীরে (এমনকি মাঝারি মানের দামের স্টাফ)। সম্ভবত, আপনি কেবলমাত্র কয়েকটি বাইট লেখার পরে ডিস্কের সমস্ত পথে ফ্লাশ করছেন তবেই I / O হ'ল বাধা। OTOH, UI একটি আলাদা বিষয়, আমরা মানুষ ধীর।
বেন ভয়েগট

11

আপনার কোডে যথাসম্ভব দৃ const়তা ব্যবহার করুন। এটি সংকলকটিকে আরও ভালতর অনুকূলিতকরণের অনুমতি দেয়।

এই নথিতে অন্যান্য অপ্টিমাইজেশান টিপসের বোঝা রয়েছে: সিপিপি অপ্টিমাইজেশন (যদিও কিছুটা পুরানো নথি)

হাইলাইট:

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

8
খুব বেশি, খুব কমই। যদিও এটি প্রকৃত নির্ভুলতার উন্নতি করে।
পোটোটোভটার

5
সি এবং সি ++ এ সংকলকটি অনুকূলকরণের জন্য কনট ব্যবহার করতে পারে না কারণ এটিকে দূরে ফেলে দেওয়া ভাল-সংজ্ঞায়িত আচরণ।
dsimcha

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

@ ডিডিমচা: একটি const এবং restrict যোগ্য পয়েন্টার পরিবর্তন করা অবশ্য অপরিজ্ঞাত । সুতরাং একটি সংকলক এ জাতীয় ক্ষেত্রে আলাদাভাবে অনুকূল করতে পারে।
ডায়েটারিচ এপ্প

6
@ ডিএসিমচা constএকটি constরেফারেন্স বা constঅ- constঅবজেক্টের নির্দেশকের উপরে ফেলে দেওয়া ভালভাবে সংজ্ঞায়িত। একটি আসল constঅবজেক্ট (যেমন একটি হিসাবে ঘোষিত const) পরিবর্তন করা নয়।
স্টিফেন লিন

9

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

রেফারেন্স বা পয়েন্টার দিয়ে ডেটা নিয়ে কাজ করার সময় এটিকে স্থানীয় ভেরিয়েবলগুলিতে টানুন, আপনার কাজটি করুন এবং তারপরে এটি আবার অনুলিপি করুন। (যদি না আপনি ভাল কারণ না থাকে)

0 এর বিপরীতে প্রায় বিনামূল্যে তুলনাটি ব্যবহার করুন যা বেশিরভাগ প্রসেসর আপনাকে গণিত বা লজিক অপারেশন করার সময় দেয় doing আপনি প্রায় সর্বদা == 0 এবং <0 এর জন্য একটি পতাকা পাবেন, সেখান থেকে আপনি সহজেই 3 শর্ত পেতে পারেন:

x= f();
if(!x){
   a();
} else if (x<0){
   b();
} else {
   c();
}

অন্যান্য ধ্রুবকগুলির জন্য পরীক্ষার চেয়ে প্রায় সর্বদা সস্তা।

আর একটি কৌশল হল পরিসীমা পরীক্ষার ক্ষেত্রে একটি তুলনা দূর করতে বিয়োগ ব্যবহার করা use

#define FOO_MIN 8
#define FOO_MAX 199
int good_foo(int foo) {
    unsigned int bar = foo-FOO_MIN;
    int rc = ((FOO_MAX-FOO_MIN) < bar) ? 1 : 0;
    return rc;
} 

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

সিতে স্ট্রিং ফাংশন ব্যবহার করার সময় (স্ট্রিপিপি, মেমকিপি ...) মনে রাখবেন তারা কী ফিরে আসে - গন্তব্য! আপনি প্রায়শই আপনার পয়েন্টারের অনুলিপিটিকে গন্তব্যস্থলে 'ভুলে' এবং আরও ভাল কোডটি পেতে পারেন এবং কেবল এই ফাংশনগুলির প্রত্যাবর্তন থেকে এটি ধরে ফেলতে পারেন।

আপনি যে শেষ ফাংশনটি ফিরে এসেছেন ঠিক একই জিনিসটি ফিরে পাওয়ার অপার্পটিটিটিকে কখনই উপেক্ষা করবেন না। সংকলকগুলি বাছাইয়ের ক্ষেত্রে এত দুর্দান্ত নয় যে:

foo_t * make_foo(int a, int b, int c) {
        foo_t * x = malloc(sizeof(foo));
        if (!x) {
             // return NULL;
             return x; // x is NULL, already in the register used for returns, so duh
        }
        x->a= a;
        x->b = b;
        x->c = c;
        return x;
}

অবশ্যই, আপনি যে যুক্তি বিপরীত করতে পারে যদি এবং শুধুমাত্র একটি রিটার্ন পয়েন্ট থাকে।

(আমি যে কৌশলগুলি পরে স্মরণ করেছি)

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


2
রেঞ্জ, এলএলভিএম, জিসিসি এবং আমার সংকলকটি অন্তত স্বয়ংক্রিয়ভাবে এটি করার সময় বিয়োগফল ব্যবহার করার প্রয়োজন হয় না। বিয়োগের কোডটি কী করবে এবং খুব কম কেন এটি আসলে কাজ করে তা খুব কম লোকই বুঝতে পারে।
গ্রান্টিয়ান লুপ

উপরের উদাহরণে, খ () বলা যাবে না কারণ যদি (x <0) হয় তবে একটি () বলা হবে।
এভিলটিচ

পছন্দ করুন একটি () এর সাথে কল করার ফলাফলের তুলনাটি হ'ল x
nthet

@nategoose। যদি x -3 হয় তবে x সত্য।
এভিলটিচ

@EvilTeach মধ্যে C 0 মিথ্যা এবং অন্য সব কিছুর সত্য, তাই -3 সত্য, তাই -3 মিথ্যা!
nategoose

9

আমি একটি অপ্টিমাইজিং সি সংকলক লিখেছি এবং এখানে কয়েকটি খুব দরকারী বিষয় বিবেচনা করা হচ্ছে:

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

  2. যদি গ্লোবাল ভেরিয়েবলগুলি ব্যবহার করা হয় তবে এগুলি স্থির করুন এবং সম্ভব হলে স্থির হিসাবে চিহ্নিত করুন। যদি সেগুলি একবার শুরু করা হয় (কেবলমাত্র পঠনযোগ্য) তবে স্ট্যাটিক কনস্ট ইনট ভ্যাল [] = {1,2,3,4} এর মতো একটি ইনিশিয়ালাইজার তালিকাটি ব্যবহার করা ভাল, অন্যথায় সংকলকটি আবিষ্কার করতে পারে না যে ভেরিয়েবলগুলি আসলে আরম্ভকৃত ধ্রুবক এবং ধ্রুবকগুলির সাথে ভেরিয়েবল থেকে লোডগুলি প্রতিস্থাপন করতে ব্যর্থ হবে।

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

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

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

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

  7. একাধিক শর্তে পরীক্ষা লেখার সময় সবচেয়ে সম্ভবত একটি স্থান দেয়। if (a || b || c) should should if (b || a || c) অন্যের তুলনায় সত্য হওয়ার সম্ভাবনা বেশি থাকে। সংকলকগণ সাধারণত কন্ডিশনের সম্ভাব্য মানগুলি এবং কোন শাখাগুলি বেশি নেওয়া হয় সে সম্পর্কে কিছুই জানেন না (তারা প্রোফাইল তথ্য ব্যবহার করে পরিচিত হতে পারে, তবে কয়েকটি প্রোগ্রামার এটি ব্যবহার করে)।

  8. একটি সুইচ ব্যবহার করা যেমন কোনও পরীক্ষা করার চেয়ে দ্রুত (যেমন || একটি || বি || ... || z)। প্রথম চেক করুন আপনার কম্পাইলার এই স্বয়ংক্রিয়ভাবে চলে আসে, তাহলে কিছু এবং এটা আছে আরো পাঠযোগ্য এর যদি যদিও।


7

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

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


আমার থাম্বের নিয়মটি হ'ল যদি আপনাকে গতিশীলভাবে বরাদ্দ করতে হয় তবে একটি অ্যারে পান যাতে আপনার এটি আবার করার দরকার নেই। তাদের ভেক্টর প্রেলোকল্ট করুন।
এভিলটিচ

7

একটি বোবা সামান্য টিপ, তবে এটি আপনাকে গতি এবং কোডের কিছু মাইক্রোস্কোপিক পরিমাণ সংরক্ষণ করবে।

সর্বদা একই ক্রমে ফাংশন আর্গুমেন্ট পাস করুন।

আপনার যদি f_1 (x, y, z) থাকে যা f_2 কল করে, f_2 কে f_2 হিসাবে ঘোষণা করুন (x, y, z)। এটিকে f_2 (x, z, y) হিসাবে ঘোষণা করবেন না।

এর কারণ হ'ল সি / সি ++ প্ল্যাটফর্ম এবিআই (একা কলিং কনভেনশন) নির্দিষ্ট রেজিস্টার এবং স্ট্যাকের জায়গাগুলিতে যুক্তিগুলি পাস করার প্রতিশ্রুতি দেয়। যখন যুক্তিগুলি ইতিমধ্যে সঠিক রেজিস্টারে রয়েছে তখন তাদের এদিক ওদিক ঘুরিয়ে নিতে হবে না।

বিচ্ছিন্ন কোড পড়ার সময় আমি কিছু হাস্যকর রেজিস্ট্রার বদলে দেখেছি কারণ লোকেরা এই নিয়মটি মানেনি।


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

5

দুটি কোডিং টেকনিক আমি উপরের তালিকায় দেখিনি:

একটি অনন্য উত্স হিসাবে কোড লিখে বাইপাস লিঙ্কার

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

তবে আপনি যদি আপনার প্রোগ্রামটি ভালভাবে ডিজাইন করেন তবে আপনি এটি একটি অনন্য সাধারণ উত্সের মাধ্যমেও সংকলন করতে পারেন। এটি ইউনিট 1.c এবং ইউনিট 2 সিপি সংকলনের পরিবর্তে উভয় বস্তুর সাথে লিঙ্ক করুন, all.c কম্পাইল করুন যা কেবল # ইউনিট 1 সি এবং ইউনিট 2.c অন্তর্ভুক্ত করে। সুতরাং আপনি সমস্ত সংকলক অপ্টিমাইজেশন থেকে উপকৃত হবে।

এটি কেবল সি ++ (এবং সি তে করা আরও সহজ) প্রোগ্রামগুলি শিরোনাম লেখার মতো।

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

এই সহজ কৌশলটি ব্যবহার করে আমি এমন কিছু প্রোগ্রাম তৈরি করতে গিয়েছিলাম যা আমি দশগুণ দ্রুত লিখেছি!

রেজিস্টার কীওয়ার্ডের মতো, এই কৌশলটিও শীঘ্রই অচল হয়ে যেতে পারে। সংযোগকারীদের মাধ্যমে লিঙ্কারের মাধ্যমে অনুকূলিতকরণ সমর্থন করা শুরু করে অপ্টিমাইজ করা জিসিসি: লিঙ্ক টাইম অপ্টিমাইজেশন

পারমাণবিক কাজগুলি লুপগুলিতে পৃথক করুন

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

এটির সাথে সতর্ক থাকুন (এই কৌশলটি ব্যবহার করে প্রোফাইল পারফরম্যান্সগুলি বা না) যেমন নিবন্ধটি ব্যবহারের পাশাপাশি এটি উন্নতগুলির চেয়ে কম পারফরম্যান্স দিতে পারে।


2
হ্যাঁ, এখন অবধি, এলটিও এই পোস্টের প্রথমার্ধকে অনর্থক এবং সম্ভবত খারাপ পরামর্শ দিয়েছে।
আন্ডারস্কোর_১১

@ আসন্ডার_ডি: এখনও কিছু সমস্যা রয়েছে (বেশিরভাগ রফতানি প্রতীকগুলির দৃশ্যমানতার সাথে সম্পর্কিত), তবে নিছক পারফরম্যান্সের দৃষ্টিকোণ থেকে সম্ভবত আর কোনও নেড নেই।
ক্রিস

4

আমি এটি এসকিউএলাইটে আসলে দেখেছি এবং তারা দাবি করে যে এটির ফলাফলের ফলাফল results 5% বাড়ে: আপনার সমস্ত কোডকে একটি ফাইলে রাখুন বা এর সমতুল্য করতে প্রিপ্রসেসর ব্যবহার করুন। এইভাবে অপ্টিমাইজারটির পুরো প্রোগ্রামটিতে অ্যাক্সেস থাকবে এবং আরও আন্তঃবিরামীয় অপ্টিমাইজেশন করতে পারে do


5
উত্সে ঘনিষ্ঠ শারীরিক সান্নিধ্যে একসাথে ব্যবহৃত ফাংশনগুলি রাখার সম্ভাবনা বৃদ্ধি পায় যে তারা বস্তু ফাইলগুলিতে একে অপরের কাছে এবং আপনার এক্সিকিউটিভের ক্ষেত্রে একে অপরের কাছে থাকবে। নির্দেশাবলীর এই উন্নত অঞ্চলটি চলমান অবস্থায় নির্দেশের ক্যাশে মিস করা এড়াতে সহায়তা করতে পারে।
paxos1977

এইআইএক্স সংকলকটির সেই আচরণকে উত্সাহিত করার জন্য একটি সংকলক সুইচ রয়েছে - কিপা [= <suboptions_list>] | -কনাইপা ইন্টারপ্রেসিডুরাল অ্যানালাইসিস (আইপিএ) নামে পরিচিত এক শ্রেণীর অনুকূলিতকরণ চালু বা কাস্টমাইজ করে।
এভিলটেক

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

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

@ ওয়ালাকোলু নিশ্চিতভাবেই, এটি ফয়ারের তারিখের তারিখ। এফডব্লিউআইডাব্লু, আমি আজ প্রথমবারের মতো জিসিসির এলটিও ব্যবহার করেছি এবং - অন্য সমস্ত কিছু সমান হচ্ছে -O3- এটি আমার প্রোগ্রামের মূল আকারের 22% বিস্ফোরিত হয়েছিল। (এটি সিপিইউ-বাউন্ডেড নয়, তাই গতি সম্পর্কে আমার তেমন কিছু বলার দরকার নেই))
আন্ডারস্কোর_১১

4

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

উদাহরণ:

int fac2(int x, int cur) {
  if (x == 1) return cur;
  return fac2(x - 1, cur * x); 
}
int fac(int x) {
  return fac2(x, 1);
}

অবশ্যই এই উদাহরণটির কোনও সীমানা যাচাই করা নেই।

দেরীতে সম্পাদনা

যদিও আমার কোড সম্পর্কে সরাসরি জ্ঞান নেই; এটি স্পষ্ট বলে মনে হয় যে এসকিউএল সার্ভারে সিটিই ব্যবহারের প্রয়োজনীয়তাগুলি বিশেষভাবে তৈরি করা হয়েছিল যাতে এটি লেজ-শেষ পুনরাবৃত্তির মাধ্যমে অনুকূলিত করতে পারে।


1
সি সম্পর্কে প্রশ্নটি সি লেজ-পুনরাবৃত্তি সরিয়ে দেয় না, সুতরাং লেজ বা অন্যান্য পুনরাবৃত্তি, যদি পুনরাবৃত্তি খুব গভীর হয় তবে স্ট্যাকটি ফুঁ দিতে পারে।
টোড

1
আমি গোটো ব্যবহার করে কলিং কনভেনশন ইস্যুকে এড়িয়ে চলেছি। সেভাবে ওভারহেড কম রয়েছে।
এভিলটিচ

2
@ হোগান: এটি আমার কাছে নতুন। আপনি কি কোনও সংকলককে এটি নির্দেশ করতে পারেন? এবং আপনি কীভাবে নিশ্চিত হতে পারেন যে এটি এটি যথার্থই অনুকূলিত করে? এটি যদি এটি করে তবে এটির এটি নিশ্চিত হওয়া দরকার to এটি এমন কিছু নয় যা আপনি আশা করেন যে সংকলক অপ্টিমাইজারটি উঠবে (যেমন ইনলাইনিং যা কাজ করতে পারে বা নাও পারে)
তুষারপাত

6
@ হোগান: আমি সংশোধন করেছি। আপনি ঠিক বলেছেন যে জিসিসি এবং এমএসভিসি দুজনেই লেজ পুনরাবৃত্তি অপ্টিমাইজেশন করে।
টোড

5
এই উদাহরণটি পুচ্ছ পুনরাবৃত্তি নয় কারণ এটি পুনরাবৃত্তি কলটি শেষ নয়, এটির গুণটি।
ব্রায়ান ইয়ং

4

বার বার একই কাজ করবেন না!

একটি সাধারণ অ্যান্টিপ্যাটার্ন যা আমি দেখি তা এই লাইনগুলি বরাবর চলে:

void Function()
{
   MySingleton::GetInstance()->GetAggregatedObject()->DoSomething();
   MySingleton::GetInstance()->GetAggregatedObject()->DoSomethingElse();
   MySingleton::GetInstance()->GetAggregatedObject()->DoSomethingCool();
   MySingleton::GetInstance()->GetAggregatedObject()->DoSomethingReallyNeat();
   MySingleton::GetInstance()->GetAggregatedObject()->DoSomethingYetAgain();
}

সংকলক আসলে functions সমস্ত ফাংশন সব সময় কল করতে হবে। আপনাকে ধরেই রেখেছি, প্রোগ্রামার, জানে যে একীভূত বস্তু এই সমস্ত কলগুলির উপর নির্ভর করে না, যা পবিত্র সমস্ত কিছুর ভালবাসার জন্য ...

void Function()
{
   MySingleton* s = MySingleton::GetInstance();
   AggregatedObject* ao = s->GetAggregatedObject();
   ao->DoSomething();
   ao->DoSomethingElse();
   ao->DoSomethingCool();
   ao->DoSomethingReallyNeat();
   ao->DoSomethingYetAgain();
}

সিঙ্গেলটন গেটের ক্ষেত্রে কলগুলি খুব বেশি ব্যয়বহুল নাও হতে পারে তবে এটি অবশ্যই একটি ব্যয় (সাধারণত, "বস্তুটি তৈরি হয়েছে কিনা তা পরীক্ষা করে দেখুন, এটি না থাকলে এটি তৈরি করুন, তবে এটি ফিরিয়ে দিন)" এই শৃঙ্খলা বাহিনী আরও জটিল হয়ে উঠবে, আমাদের আরও সময় নষ্ট হবে।


3
  1. সমস্ত পরিবর্তনশীল ঘোষণার জন্য সম্ভব সর্বাধিক স্থানীয় সুযোগ ব্যবহার করুন।

  2. constযখনই সম্ভব ব্যবহার করুন

  3. আত ব্যবহার রেজিস্টার যদি না তোমাদের সাথে এবং এটা ছাড়া প্রোফাইলে পরিকল্পনা

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

অন্ধভাবে রেজিস্টার কীওয়ার্ডটি ব্যবহার করা আপনার অপ্টিমাইজেশনের ক্ষতি করতে যতটা সহায়তা করতে পারে, আপনি সমাবেশ আউটপুট বা প্রোফাইলটি না দেখলে কী হবে তা জানা খুব কঠিন।

কোডের বাইরে ভাল পারফরম্যান্স পাওয়ার ক্ষেত্রে আরও কিছু বিষয় রয়েছে; আপনার ডেটা স্ট্রাকচারকে উদাহরণস্বরূপ ক্যাশে সুসংহত করার জন্য নকশা করা। তবে প্রশ্নটি ছিল অপটিমাইজার সম্পর্কে।



3

আমাকে এমন কিছু মনে করিয়ে দেওয়া হয়েছিল যা আমি একবার মুখোমুখি হয়েছিলাম, যেখানে লক্ষণটি হ'ল আমরা স্মৃতি থেকে বেরিয়ে এসেছি, তবে ফলাফলটি ছিল যথেষ্ট পরিমাণে কর্মক্ষমতা (সেইসাথে মেমরির পদক্ষেপে বিশাল হ্রাস) increased

এই ক্ষেত্রে সমস্যাটি হ'ল আমরা যে সফ্টওয়্যারটি ব্যবহার করছিলাম তা হ'ল টন অল্প বরাদ্দ। যেমন, এখানে চারটি বাইট বরাদ্দ করুন, সেখানে ছয় বাইট ইত্যাদি etc.-১২ বাইট পরিসরে চলমান প্রচুর পরিমাণে ছোট্ট অবজেক্ট। সমস্যাটি এত বেশি ছিল না যে প্রোগ্রামটির জন্য প্রচুর পরিমাণে ছোট ছোট জিনিস প্রয়োজন ছিল, এটি স্বতন্ত্রভাবে প্রচুর পরিমাণে ছোট ছোট জিনিস বরাদ্দ করেছিল, যা প্রতিটি বরাদ্দকে (এই নির্দিষ্ট প্ল্যাটফর্মে) 32 বাইটে ফুলিয়ে দেয়।

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

সমাধানের অন্য অংশটি হ'ল ম্যানুয়ালি-পরিচালিত চর * সদস্যদের প্রচলিত ব্যবহারকে এসএসও (ছোট স্ট্রিং অপ্টিমাইজেশন) স্ট্রিংয়ের সাথে প্রতিস্থাপন করা। সর্বনিম্ন বরাদ্দ 32 বাইট হওয়ায় আমি একটি স্ট্রিং ক্লাস তৈরি করেছি যা একটি চরের * এর পিছনে এম্বেড করা ২৮-অক্ষরযুক্ত বাফার ছিল, সুতরাং আমাদের স্ট্রিংগুলির 95% অতিরিক্ত বন্টন করার প্রয়োজন ছিল না (এবং তারপরে আমি নিজেই প্রায় প্রতিটি উপস্থিতি ম্যানুয়ালি প্রতিস্থাপন করেছি) এই নতুন ক্লাসের সাথে এই লাইব্রেরিতে চর * এটি মজাদার ছিল বা না)। এটি মেমরি টুকরো টুকরো করার জন্যও একটি টন সহায়তা করেছিল, যা পরে অন্যান্য নির্দেশিত-অবজেক্টের জন্য রেফারেন্সের লোকাল বাড়িয়ে তোলে এবং একইভাবে পারফরম্যান্স লাভও করেছিল।


3

এই উত্তরটি সম্পর্কে @ এসএমএল্টারের মন্তব্য থেকে আমি শিখেছি একটি ঝরঝরে কৌশল , কিছু শর্ত অনুসারে বিভিন্ন বস্তু ফেরত পাঠানোর সময়ও সংকলকরা অনুলিপিটি করতে সক্ষম করে:

// before
BigObject a, b;
if(condition)
  return a;
else
  return b;

// after
BigObject a, b;
if(condition)
  swap(a,b);
return a;

2

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

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


রেকার্সনটিকে স্ট্যাকে রূপান্তর করা ompf.org- এ রাইট্রেসার বিকাশকারী এবং অন্যান্য রেন্ডারিং অ্যালগরিদম লেখার ক্ষেত্রে একটি অনুমিত অপ্টিমাইজেশন।
টম

... আমার এটিকে যোগ করা উচিত, আমার ব্যক্তিগত রেট্র্যাকার প্রকল্পের বৃহত্তম ওভারহেডটি কমপিউটিভ প্যাটার্নটি ব্যবহার করে একটি বাউন্ডিং-ভলিউম স্তরক্রমের মাধ্যমে ভেটেবল-ভিত্তিক পুনরাবৃত্তি। এটি সত্যই কেবল গাছ হিসাবে কাঠামোযুক্ত নেস্টেড বাক্সগুলির একগুচ্ছ, তবে প্যাটার্নটি ব্যবহারের ফলে ডেটা ফোলাভাব হয় (ভার্চুয়াল টেবিল পয়েন্টার) এবং নির্দেশের একাত্মতা হ্রাস করে (একটি ছোট / টাইট লুপ কী হতে পারে এখন ফাংশন কলগুলির একটি শৃঙ্খল)
টম

2

এখানে আমার অপ্টিমাইজেশনের পরামর্শের দ্বিতীয় অংশ। আমার প্রথম পরামর্শের মতো এটি সাধারণ উদ্দেশ্য, ভাষা বা প্রসেসর নির্দিষ্ট নয়।

সংকলক ম্যানুয়াল পুরোপুরি পড়ুন এবং এটি আপনাকে কী বলছে তা বুঝতে পারেন। সংকলকটিকে এর সর্বোচ্চতম ব্যবহার করুন Use

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

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

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

শুভেচ্ছা সহ

ছাপ

আমি যখন প্রথম কোনও কোডের টুকরোটি তুলি আমি সাধারণত 1.4 - 2.0 গুণ বেশি পারফরম্যান্সের একটি ফ্যাক্টর পেতে পারি (যেমন কোডের নতুন সংস্করণটি 1 / 1.4 বা পুরানো সংস্করণের সময়ের 1/2 তে চলে) একটি এর মধ্যে সংকলক পতাকা সহ fiddling দ্বারা দিন বা দুই। মঞ্জুর, এটি আমার শ্রেষ্ঠত্বের লক্ষণ না দিয়ে বিজ্ঞানীদের মধ্যে যে আমি কাজ করি তার বেশিরভাগ সূত্রপাতকারীদের মধ্যে সংকলক জ্ঞানের অভাবের বিষয়ে একটি মন্তব্য হতে পারে। সংকলক পতাকা সর্বোচ্চে সেট করা (এবং এটি খুব কমই -O3) 1.05 বা 1.1 এর অন্য একটি ফ্যাক্টর পেতে কয়েক মাস কঠোর পরিশ্রম করতে পারে


2

যখন ডিসি তার আলফা প্রসেসরগুলি নিয়ে বেরিয়ে আসে, একটি ফাংশনে যুক্তির সংখ্যা 7 এর নিচে রাখার জন্য একটি সুপারিশ ছিল কারণ সংকলকটি সর্বদা স্বয়ংক্রিয়ভাবে নিবন্ধগুলিতে 6 টি যুক্তি যুক্ত করার চেষ্টা করবে।


x86-64 বিটটি প্রচুর নিবন্ধক-পাস হওয়া পরামিতিগুলিরও অনুমতি দেয়, যা ফাংশন কল ওভারহেডে নাটকীয় প্রভাব ফেলতে পারে।
টম

1

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

অপ্টিমাইজার আপনার প্রোগ্রামের পারফরম্যান্সকে প্রান্তিকভাবে সহায়তা করবে।


3
এটি কেবল তখনই কার্যকর হয় যদি সংযোজন "ইন্টারফেস" নিজেরাই অপ্টিমাইজেশনের জন্য উপযুক্ত। একটি ইন্টারফেস সহজাত "ধীর" হতে পারে, উদাহরণস্বরূপ অপ্রয়োজনীয় চেহারা বা গণনা জোর করে বা খারাপ ক্যাশে অ্যাক্সেস জোর করে।
টম

1

আপনি এখানে ভাল উত্তর পাচ্ছেন, তবে তারা ধরে নিচ্ছেন যে আপনার প্রোগ্রামটি শুরু হতে অনুকূলের খুব কাছাকাছি রয়েছে, এবং আপনি বলছেন

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

আমার অভিজ্ঞতায় কোনও প্রোগ্রাম সঠিকভাবে লেখা হতে পারে তবে এর অর্থ এটি সর্বোত্তমের কাছাকাছি নেই। এটি পেতে অতিরিক্ত কাজ লাগে।

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

এটি সম্পন্ন হওয়ার পরে, মাইক্রো অপ্টিমাইজেশন (হট স্পটগুলির) আপনাকে একটি ভাল বেতন দিতে পারে।


1

আমি ইন্টেল সংকলক ব্যবহার করি উইন্ডোজ এবং লিনাক্স উভয় উপর।

যখন কম বা কম কাজ করে আমি কোডটি প্রোফাইল করি। তারপরে হটস্পটগুলিতে স্তব্ধ থাকুন এবং সংকলকটিকে আরও ভাল কাজ করার জন্য কোডটি পরিবর্তন করার চেষ্টা করুন।

যদি কোনও কোড একটি গণনামূলক হয় এবং এতে প্রচুর লুপ থাকে - ইন্টেল সংকলকটিতে ভেক্টরাইজেশন রিপোর্টটি খুব সহায়ক - সাহায্যে 'ভেক-রিপোর্ট' সন্ধান করুন।

সুতরাং মূল ধারণা - পারফরম্যান্সের সমালোচনা কোডটি পোলিশ করুন। বাকি হিসাবে - অগ্রাধিকারটি সঠিক এবং রক্ষণাবেক্ষণযোগ্য - সংক্ষিপ্ত ফাংশন, স্পষ্ট কোড যা 1 বছর পরে বোঝা যায়।


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

1
সি-স্টাইলে আরও লেখার চেষ্টা করা হচ্ছে (বনাম, সি ++ তে) উদাহরণস্বরূপ ভার্চুয়াল ফাংশনগুলি এড়িয়ে চলা W / o পরম প্রয়োজন, বিশেষত যদি তাদের প্রায়শই ডাকা হয়, অ্যাডরাফগুলি এড়িয়ে চলুন .. এবং সমস্ত শীতল জিনিস (এটি যদি সত্যিই প্রয়োজন না হয় তবে আবার)। ইনলাইনিংয়ের জন্য কোড সহজ লিখুন - কম পরামিতি, কম "যদি" -এস। সম্পূর্ণ প্রয়োজন না হলে বৈশ্বিক ভেরিয়েবল ব্যবহার করবেন না। ডেটা স্ট্রাকচারে - বৃহত্তর ক্ষেত্রগুলি প্রথমে রাখুন (ডাবল, ইনট 6464 ইন্টের আগে যায়) - তাই সংকলক প্রথম ক্ষেত্রের প্রাকৃতিক আকারের কাঠামোটি প্রান্তিক করুন - পারফের জন্য ভাল প্রান্তিককরণ করুন।
জেএফ।

1
ডেটা বিন্যাস এবং অ্যাক্সেস পারফরম্যান্সের জন্য একেবারে গুরুত্বপূর্ণ। সুতরাং প্রোফাইলিংয়ের পরে - আমি কখনও কখনও অ্যাক্সেসের লোকেশন অনুসরণ করে কিছু কাঠামো ভেঙে ফেলি। আরও একটি সাধারণ কৌশল - ইনট বা আকার-টি বনাম চার্জ ব্যবহার করুন - এমনকি ডেটা মানগুলিও ছোট - বিভিন্ন পারফেক্ট এড়ানো। আঞ্চলিক রেজিস্ট্রি স্টলগুলি নিয়ে সমস্যাগুলি লোড করার জন্য পেনাল্টি সঞ্চয় করে। অবশ্যই যখন এই জাতীয় ডেটার বড় অ্যারেগুলির প্রয়োজন হয় তখন এটি প্রযোজ্য নয়।
জেএফ।

আরও একটি - আসল প্রয়োজন না থাকলে সিস্টেম কলগুলি এড়ান :) - এগুলি খুব ব্যয়বহুল
জেএফ।

2
@ জেফ: আপনার উত্তরটি আমি +1 করেছি, তবে অনুগ্রহ করে আপনি মন্তব্যগুলি থেকে উত্তরটি বডিটিতে উত্তর স্থানান্তর করতে পারেন? এটি পড়া সহজ হবে।
মার্চকে ক্রিস করুন

1

আমি সি ++ তে একটি অপ্টিমাইজেশন ব্যবহার করেছি এমন একটি কনস্ট্রাক্টর তৈরি করছে যা কিছুই করে না। একটি অবজেক্টটিকে একটি কার্যক্ষম অবস্থানে রাখার জন্য ম্যানুয়ালি একটি init () কল করতে হবে।

আমার এই ক্লাসগুলির একটি বৃহত্তর ভেক্টর প্রয়োজন সেই ক্ষেত্রে এটির সুবিধা রয়েছে।

আমি ভিজ্টারের জন্য স্থান বরাদ্দ করতে রিজার্ভ () বলি, তবে কনস্ট্রাক্টর বস্তুটিতে থাকা মেমরির পৃষ্ঠাটি স্পর্শ করে না। তাই আমি কিছু ঠিকানার জায়গা ব্যয় করেছি, কিন্তু বাস্তবে প্রচুর শারীরিক স্মৃতি গ্রহন করি নি। আমি সম্পর্কিত ত্রুটি সম্পর্কিত পৃষ্ঠাগুলি এড়াতে চাই।

আমি ভেক্টরটি পূরণ করার জন্য যেহেতু বস্তু উত্পন্ন করি, আমি সেগুলি init () ব্যবহার করে সেট করি। এটি আমার মোট পৃষ্ঠার ত্রুটিগুলিকে সীমাবদ্ধ করে এবং ভেক্টরটি পূরণ করার সময় এটির আকার পরিবর্তন করার প্রয়োজনটিকে এড়িয়ে যায়।


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

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

বরং আমাকে অবাক করে দেয়। আপনি কোন সি ++ এবং এসটিএল বাস্তবায়ন ব্যবহার করছিলেন?
ডেভিড থর্নলি

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

1
@ ডেভিড - বাস্তবায়নটি এআইএক্স-এ হয়েছিল।
এভিলটিচ

1

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

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


0

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


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

+1 নীল, এবং এর একটি নির্দিষ্ট উপস্থিতি হ'ল ইনটেল হার্ডওয়্যারটিতে "k৪ কে আলিয়াজিং"।
টম

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

0

উত্স ফাইলের শীর্ষে ছোট এবং / অথবা প্রায়শই বলা ফাংশন রাখুন। এটি কম্পাইলারের পক্ষে ইনলাইনের জন্য সুযোগগুলি খুঁজে পেতে সহজ করে তোলে।


সত্যি? আপনি কি এর জন্য একটি যুক্তি এবং উদাহরণ উদ্ধৃত করতে পারেন? এটিকে অসত্য বলছেন না, কেবল এটি অবস্থানের পক্ষে গুরুত্বপূর্ণ sounds
আন্ডারস্কোর_ডি

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

আমি ধরে নিয়েছি সংকলকরা শারীরিক ফাংশন ক্রমের পরিবর্তে বিমূর্ত কল গ্রাফগুলি বন্ধ করে দেবেন, যার অর্থ এটি বিবেচ্য নয়। অবশ্যই, আমি মনে করি এটি অতিরিক্ত সতর্কতা অবলম্বন করতে ক্ষতি করে না - বিশেষ করে যখন, পারফরম্যান্স একপাশে রাখা হয়, আইএমও এটি কল করে তাদের আগে ডাকা ফাংশনগুলি সংজ্ঞায়িত করা আরও যুক্তিযুক্ত বলে মনে হয়। আমাকে পারফরম্যান্স পরীক্ষা করতে হবে তবে এটি যদি গুরুত্বপূর্ণ হয় তবে অবাক হবেন, তবে ততক্ষণে আমি অবাক হওয়ার জন্য উন্মুক্ত!
আন্ডারস্কোর_ডি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.