সি ++ নিম্ন-স্তরের অপ্টিমাইজেশন টিপস [বন্ধ]


79

ধরে নিচ্ছি আপনার ইতিমধ্যে সেরা-পছন্দসই অ্যালগরিদম রয়েছে, সি ++ কোডের বাইরে মিষ্টি মিষ্টি ফ্রেমের হারের শেষ কয়েক ফোঁটা বার করার জন্য আপনি কোন নিম্ন-স্তরের সমাধানগুলি দিতে পারেন?

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


1
এই একটি খেলা উন্নয়ন প্রশ্ন ও না এই মত একটি সাধারণ প্রোগ্রামিং প্রশ্ন তোলে: stackoverflow.com/search?q=c%2B%2B+optimization
ড্যানি Varod

@ ড্যানি - এটি সম্ভবত একটি সাধারণ প্রোগ্রামিং প্রশ্ন হতে পারে। এটি অবশ্যই গেমস প্রোগ্রামিং সম্পর্কিত একটি প্রশ্ন। আমি মনে করি এটি উভয় সাইটেই একটি কার্যকর প্রশ্ন।
স্মিশেরি

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

@ ড্যানি - সত্য, কিছু প্রশ্ন একটি সাইটে বা অন্যটিতে "আরও" প্রাসঙ্গিক হবে; তবে আমি কোনও প্রাসঙ্গিক প্রশ্ন ফিরিয়ে দিতে চাই না কারণ এগুলি অন্য সাইটে জিজ্ঞাসা করা যেতে পারে।
স্মিশেরি

উত্তর:


76

আপনার ডেটা বিন্যাস অপ্টিমাইজ করুন! (এটি কেবল সি ++ এর চেয়েও বেশি ভাষায় প্রযোজ্য)

আপনি আপনার ডেটা, আপনার প্রসেসর, মাল্টি-কোরকে সুন্দরভাবে পরিচালনা করা ইত্যাদির জন্য বিশেষভাবে এটি তৈরি করতে বেশ গভীর যেতে পারেন তবে মূল ধারণাটি হ'ল:

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

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

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


লিঙ্কযুক্ত ক্যাশে সমন্বয় পৃষ্ঠায় সি উদাহরণটি চেষ্টা করে দেখার মতো। আমি যখন এই সম্পর্কে প্রথম জানতে পারলাম তখন আমি কতটা পার্থক্য বোধ করি তা নিয়ে হতবাক হয়ে গিয়েছিলাম।
নীল

9
এছাড়াও অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিং উপস্থাপনা (সনি আর অ্যান্ড ডি) ( গবেষণা. scee.net/files/preferencesations / gcapaustralia09/…) - এর মেক অ্যাক্টনের ( সেল্পার পারফরম্যান্স.বিব্রন 3d.com পার্টিকালস / র সেল্পার পারফরম্যান্স নিবন্ধ) এর দুর্দান্ত ক্ষতিগুলি দেখুন index.html )। ব্লগের ভেতর থেকে নোয়েল লোলোপিসের গেমগুলিও প্রায়শই এই বিষয়গুলিতে স্পর্শ করে ( গেমসফ্রমউইথিন ডটকম )। আমি
পিটফলস

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

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

84

একটি খুব, খুব নিম্ন-স্তরের টিপ, তবে এটি কার্যকর হতে পারে:

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

if(__builtin_expect(entity->extremely_unlikely_flag, 0)) {
  // code that is rarely run
}

আমি এটির যথাযথ ব্যবহারের সাথে 10-10% স্পিডআপ দেখেছি।


1
আমি পারলে দু'বার ভোট দিতাম।
টেনপেন

10
+1, লিনাক্স কার্নেলটি শিডিয়ুলার কোডে মাইক্রোপটিমাইজেশনের জন্য এটি ব্যাপকভাবে ব্যবহার করে এবং এটি নির্দিষ্ট কোডের পাথগুলিতে উল্লেখযোগ্য পার্থক্য করে।
গ্রেফ্যাড

2
দুর্ভাগ্যক্রমে, ভিজ্যুয়াল স্টুডিওতে কোনও ভাল সমতুল্য বলে মনে হচ্ছে না। stackoverflow.com/questions/1440570/...
mmyers

1
তাহলে কোন ফ্রিকোয়েন্সিতে প্রত্যাশিত মানটি পারফরম্যান্স অর্জনের জন্য সাধারণত সঠিক হতে হবে? 49/50 বার? বা 999999/1000000 বার?
ডগলাস

36

আপনি যে হার্ডওয়্যারটি চালাচ্ছেন তা হ'ল আপনাকে প্রথমে বুঝতে হবে। কিভাবে এটি শাখা পরিচালনা করে? ক্যাচিংয়ের কী হবে? এটিতে কি সিমডি নির্দেশিকা আছে? এটি কয়টি প্রসেসর ব্যবহার করতে পারে? এটি কি অন্য কিছুর সাথে প্রসেসরের সময় ভাগ করে নিতে হবে?

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

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

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

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

আপনার যদি এখনও আরও গতির প্রয়োজন হয় তবে সমান্তরালে যান। আপনার যদি PS3 এ চালানোর সুবিধা হয় তবে এসপিইউগুলি আপনার বন্ধু। তাদের ব্যবহার করুন, তাদের ভালবাসেন। যদি আপনি ইতিমধ্যে একটি সিমডি সমাধান লিখেছেন তবে আপনি এসপিইউতে চলে যাওয়ার একটি বিশাল সুবিধা পাবেন।

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

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

এবং তারপরে এটি আবার প্রোফাইল করুন।


31

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

দ্বিতীয় পদক্ষেপ: উত্পন্ন সমাবেশটি দেখুন। সি ++ টেবিলটিতে প্রচুর অন্তর্নিহিত কোড জেনারেশন নিয়ে আসে। কখনও কখনও, এটি আপনার অজান্তেই আপনার দিকে ঝাঁপিয়ে পড়ে।

তবে ধরে নিচ্ছি এটি সত্যই ধাতব সময় থেকে প্যাডেল হচ্ছে: প্রোফাইল। সিরিয়াসলি। এলোমেলোভাবে "পারফরম্যান্স ট্রিকস" প্রয়োগ করা যতটা সাহায্য করবে ততই আহত হওয়ার সম্ভাবনা রয়েছে।

তারপরে, সমস্ত কিছুই আপনার বাধা কীগুলির উপর নির্ভর করে।

ডেটা ক্যাশে মিস => আপনার ডেটা বিন্যাস অপ্টিমাইজ। এখানে একটি সূচনা পয়েন্ট: http://gamesfromwithin.com/data-oriented- ডিজাইন

কোড ক্যাশে মিস করে => ভার্চুয়াল ফাংশন কলগুলি, অত্যধিক কলস্ট্যাকের গভীরতা ইত্যাদি দেখুন bad খারাপ পারফরম্যান্সের একটি সাধারণ কারণ হ'ল বেস ক্লাসগুলি অবশ্যই ভুল বিশ্বাস ভার্চুয়াল ।

অন্যান্য সাধারণ সি ++ পারফরম্যান্স ডুবে:

  • অতিরিক্ত বরাদ্দ / অবলম্বন যদি এটি সম্পাদন সমালোচনা করে থাকে তবে রানটাইমটিতে কল করবেন না। কখনো।
  • কপি নির্মাণ। যেখানেই পারেন এড়িয়ে চলুন। যদি এটি কোনও স্থির রেফারেন্স হতে পারে তবে এটি তৈরি করুন।

আপনি সমাবেশটি দেখলে উপরের সমস্তগুলি অবিলম্বে সুস্পষ্ট, সুতরাং উপরে দেখুন;)


19

অপ্রয়োজনীয় শাখা সরান

কিছু প্ল্যাটফর্ম এবং কিছু সংকলক সহ, শাখাগুলি আপনার পুরো পাইপলাইন ফেলে দিতে পারে, তাই () ব্লকগুলি ব্যয়বহুল হতে পারে এমন কি তুচ্ছ নয়।

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

float result = 0;
if (foo > bar) { result = 2.0f; }
else { result = 1.0f; }

হয়ে:

float result = fsel(foo-bar, 2.0f, 1.0f);

যখন প্রথম প্যারামিটার 0 এর চেয়ে বড় বা সমান হয়, তখন দ্বিতীয় প্যারামিটারটি ফিরে আসে, অন্যথায় তৃতীয়।

শাখাটি হারাতে দামটি হ'ল যদি {} এবং অন্য {} ব্লক উভয়ই কার্যকর করা হবে, সুতরাং যদি কোনও ব্যয়বহুল ক্রিয়াকলাপ হয় বা কোনও এনইউএল পয়েন্টার অবলম্বন করে তবে এই অপটিমাইজেশন উপযুক্ত নয়।

কখনও কখনও আপনার সংকলক ইতিমধ্যে এই কাজটি সম্পন্ন করেছে, তাই প্রথমে আপনার সমাবেশটি পরীক্ষা করুন।

এখানে শাখা এবং fsel সম্পর্কিত আরও তথ্য:

http://assemblyrequired.crashworks.org/tag/intrinsics/


ভাসমান ফলাফল = (foo> বার)? 2.f: 1.f
নাইট 666

3
@ নাইট 6666: এটি এখনও যে কোনও জায়গায় একটি শাখা তৈরি করবে যে দীর্ঘদিন "যদি" করত। আমি এটিকে বলি কারণ এআরএম-এ, কমপক্ষে, এর মতো ছোট ছোট সিক্যুয়েন্সগুলি শর্তাধীন নির্দেশাবলীর সাথে প্রয়োগ করা যেতে পারে যা শাখাগুলির প্রয়োজন হয় না।
ক্রিসবুটো

1
@ নাইট 66 you're6 যদি আপনি ভাগ্যবান হন তবে সংকলক এটিকে একটি ফসলে পরিণত করতে পারে, তবে এটি নিশ্চিত নয়। এফডাব্লুআইডাব্লু, আমি সাধারণত একটি তৃতীয় অপারেটরের সাথে সেই স্নিপেট লিখব এবং তারপরে পরে প্রোফাইলার রাজি হলে fsel এ অনুকূলিতকরণ করব on
টেন্পেন

আইএ 32 তে আপনি পরিবর্তে সিএমওভিসিপি পেয়েছেন।
স্কিজে

ব্লুরাজা.com / blog / 285/… দেখুন (নোট করুন যে এই ক্ষেত্রে, সংকলকটি যদি কোনও ভাল হয় তবে এটি নিজেই এটি অনুকূল করে তুলতে সক্ষম হওয়া উচিত, সুতরাং এটি আপনার সাধারণত উদ্বিগ্ন হওয়ার মতো বিষয় নয়)
ব্লুরাজা - ড্যানি পিফ্লুঘোফাইট

16

মেমরি অ্যাক্সেস এবং বিশেষত এলোমেলো যেকোন মূল্যে এড়িয়ে চলুন।

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

আপনি এই নিয়মটি অন্য চারপাশেও পড়তে পারেন: মেমরি অ্যাক্সেসের মধ্যে যতটা সম্ভব গণনা করুন।


13

সংকলক অন্তঃসত্ত্ব ব্যবহার করুন।

নিশ্চিত করুন যে সংকলকটি নির্দিষ্ট ক্রিয়াকলাপগুলির জন্য আন্তঃব্যক্তিগুলি ব্যবহার করে সবচেয়ে কার্যকরী সমাবেশ তৈরি করছে - ফাংশন কলগুলির মতো দেখতে এমন কনস্ট্রাক্টগুলি যে সংকলকটি অনুকূলিত সমাবেশে পরিণত হয়:

এখানে ভিজ্যুয়াল স্টুডিওর জন্য একটি রেফারেন্স এবং এখানে জিসিসির একটি


11

অপ্রয়োজনীয় ভার্চুয়াল ফাংশন কলগুলি সরান

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

আপনি এটি বেশ কয়েকটি উপায়ে করতে পারেন। কখনও কখনও আপনি উত্তরাধিকারের প্রয়োজন না হওয়ার জন্য কেবল ক্লাসগুলি পুনরায় লিখতে পারেন - সম্ভবত এটি দেখা যায় যে মেশিনগান হ'ল অস্ত্রগুলির একমাত্র উপক্লাস, এবং আপনি সেগুলি একত্রিত করতে পারেন।

আপনি সংকলন-কাল পলিমারফিজম সহ রান-টাইম পলিমারফিজম প্রতিস্থাপন করতে টেমপ্লেটগুলি ব্যবহার করতে পারেন। এটি কেবলমাত্র তখনই কাজ করে যদি আপনি রানটাইমের সময় আপনার অবজেক্টের উপপ্রকার জানেন এবং একটি বড় পুনর্লিখন হতে পারে।


9

আমার মূল নীতিটি: এমন কিছু করবেন না যা প্রয়োজনীয় নয়

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

এর অর্থ এই নয় যে আপনি একটি খারাপ অ্যালগরিদম ব্যবহার করছেন। এর অর্থ হতে পারে আপনি উদাহরণস্বরূপ, প্রতিটি ফ্রেম যা খুব অল্প সময়ের জন্য (বা সম্পূর্ণ প্রাক্কলকযুক্ত) ক্যাশে হতে পারে calc

সত্যই নিম্ন-স্তরের অপ্টিমাইজেশনে কোনও প্রচেষ্টা করার আগে আমি সর্বদা এই পদ্ধতির চেষ্টা করি।


2
এই প্রশ্নটি ধরে নিয়েছে যে আপনি ইতিমধ্যে আপনার যাবতীয় কাঠামোগত জিনিসগুলি সম্পন্ন করেছেন।
টেনপেন

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

2
... তবে কখনও কখনও আপনি শাখার পরিবর্তে ফলাফলটি পরে ফেলে দিচ্ছেন এমনকি গণনাটি করা দ্রুততর হতে পারে।
টেনপেন

9

সিমডি (এসএসই দ্বারা) ব্যবহার করুন, যদি আপনি ইতিমধ্যে না করেন। গামসূত্র এ সম্পর্কে একটি দুর্দান্ত নিবন্ধ আছে । আপনি নিবন্ধের শেষে উপস্থাপিত লাইব্রেরি থেকে উত্স কোডটি ডাউনলোড করতে পারেন।


6

সিপিইউ পাইপলাইনটির আরও ভাল ব্যবহার করতে নির্ভরতা শৃঙ্খলাগুলি হ্রাস করুন।

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

উদাহরণ:

float *data = ...;
int length = ...;

// Slow version
float total = 0.0f;
int i;
for (i=0; i < length; i++)
{
  total += data[i]
}

// Fast version
float total1, total2, total3, total4;
for (i=0; i < length-3; i += 4)
{
  total1 += data[i];
  total2 += data[i+1];
  total3 += data[i+2];
  total4 += data[i+3];
}
for (; i < length; i++)
{
  total += data[i]
}
total += (total1 + total2) + (total3 + total4);

4

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

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

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


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

1
আমার উত্তরটি দেখুন: ও (লগ এন)। এছাড়াও, আপনি যদি আধা মিলিসেকেন্ড সন্ধান করেন তবে আপনাকে আরও উচ্চ স্তরের দিকে তাকাতে হবে। এটি আপনার ফ্রেম সময়ের 3%!
রাহেল ব্লাম

4

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

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

প্রযুক্তিগতভাবে 'সীমাবদ্ধ' স্ট্যান্ডার্ড সি ++ তে বিদ্যমান নেই, তবে প্ল্যাটফর্ম-নির্দিষ্ট সমতুল্য বেশিরভাগ সি ++ সংকলকগুলির জন্য উপলব্ধ, সুতরাং এটি বিবেচনা করার মতো।

আরও দেখুন: http : //सेलperformance.beyond3d.com/articles/2006/05/demystifying-t-- কঠোর- কীওয়ার্ড এইচটিএমএল


2

কনস্ট!

আপনি ডেটা সম্পর্কে সংকলককে যত বেশি তথ্য দেবেন তত অপটিমাইজেশনগুলি (কমপক্ষে আমার অভিজ্ঞতায়)।

void foo(Bar * x) {...;}

হয়ে;

void foo(const Bar * const x) {...;}

সংকলকটি এখন জানে যে পয়েন্টার এক্সটি পরিবর্তিত হচ্ছে না এবং এটি যে ডেটাটিকে নির্দেশ করছে সেটিও পরিবর্তন করবে না।

অন্যান্য যুক্ত সুবিধা হ'ল আপনি দুর্ঘটনাজনিত বাগের সংখ্যা হ্রাস করতে পারবেন, নিজেকে (বা অন্যদের) এমন জিনিসগুলি পরিবর্তন করতে বাধা দিন যা তাদের উচিত নয়।


এবং আপনার কোড বন্ধু আপনাকে ভালবাসবে!
tenpn

4
constসংকলক অপ্টিমাইজেশান উন্নতি করে না। সত্য যে সংকলকটি জানে যদি কোনও ভেরিয়েবল পরিবর্তন constহয় না তবে আরও শক্তিশালী গ্যারান্টি সরবরাহ করে না তবে এটি আরও ভাল কোড তৈরি করতে পারে True
deft_code

3
নাঃ। কনস্টের চেয়ে 'সীমাবদ্ধ' অনেক বেশি কার্যকর far গেমদেব.স্ট্যাকেক্সেঞ্জার.কম
সেকশনস /

+1 টি const নাকিসুরে কথা সাহায্যের বলার অপেক্ষা রাখে না PPL ভুল ... infoq.com/presentations/kixeye-scalability
NoSenseEtAl

2

প্রায়শই, কর্মক্ষমতা অর্জনের সর্বোত্তম উপায় হ'ল আপনার অ্যালগরিদম পরিবর্তন করা। সাধারণ যত কম বাস্তবায়ন আপনি ধাতব কাছে যেতে পারেন।

ধরে নিয়েছি যে হয়েছে ...।

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

ক্যাশে মিস মিস করবেন না। ব্যাচ প্রক্রিয়া যতটা সম্ভব আপনারা। ভার্চুয়াল ফাংশন এবং অন্যান্য নির্দেশাবলী এড়িয়ে চলুন।

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

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

কোনও ডিফল্ট সূচনা কেন তা ব্যাখ্যা করার জন্য সম্পাদিত: প্রচুর কোড বলেছেন: ভেক্টর 3 ব্লা; ব্লা = ডসোমথিং ();

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

ভেক্টর 3 ব্লে (নো ইনিট); bla = doSomething ();


/ কনস্ট্রাক্টরে আপনার সদস্যদের আরম্ভ করবেন না? এটি কীভাবে সাহায্য করে?
টেনপেন

সম্পাদিত পোস্ট দেখুন। মন্তব্য বাক্সে খাপ খায়নি।
কাজ

const Vector3 = doSomething()? তারপরে রিটার্ন-ভ্যালু অপটিমাইজেশন কৌতুক করতে পারে এবং সম্ভবত একটি নিয়োগ বা দু'জন এলিজ করতে পারে।
টেন্পেন

1

বুলিয়ান এক্সপ্রেশন মূল্যায়ন হ্রাস করুন

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

if ((foo && bar) || blah) { ... } 

হয়ে:

if ((foo & bar) | blah) { ... }

পরিবর্তে পূর্ণসংখ্যার গাণিতিক ব্যবহার। যদি আপনার foos এবং বারগুলি স্থির হয় বা যদি () এর আগে মূল্যায়ন করা হয় তবে এটি স্বাভাবিক বুলিয়ান সংস্করণের চেয়ে দ্রুত হতে পারে।

বোনাস হিসাবে পাটিগণিত সংস্করণে নিয়মিত বুলিয়ান সংস্করণের চেয়ে কম শাখা থাকে। যা অপ্টিমাইজ করার অন্য উপায় ।

বড় ক্ষতি হ'ল আপনি অলস মূল্যায়ন হারাচ্ছেন - পুরো ব্লকটি মূল্যায়ন করা হয়, তাই আপনি এটি করতে পারবেন না foo != NULL & foo->dereference()। এ কারণে এটি বিতর্কযোগ্য যে এটি বজায় রাখা খুব শক্ত এবং তাই বাণিজ্য বন্ধও দুর্দান্ত হতে পারে।


1
এটি পারফরম্যান্সের খাতিরে একটি দুর্দান্ত উদ্বেগজনক বাণিজ্য, মূলত কারণ এটি অবিলম্বে স্পষ্ট নয় যে এটি উদ্দেশ্যযুক্ত ছিল।
বব সোমার

আমি আপনার সাথে প্রায় সম্পূর্ণ একমত। আমি বললাম এটা মরিয়া!
টেনপেন

3
এটিও কি সংক্ষিপ্ত-সার্কিট ভেঙে শাখার পূর্বাভাসকে আরও বিশ্বাসযোগ্য করে তুলবে না?
ডিম

1
যদি ফু 2 হয় এবং বার 1 হয় তবে কোডটি মোটেও একই রকম আচরণ করে না। এটি এবং প্রথম দিকে মূল্যায়ন নয়, এটি আমার মনে হয় সবচেয়ে বড় ক্ষতি।

1
একাট্যালি, সি ++ এর বুলিয়ানগুলি 0 বা 1 হওয়ার গ্যারান্টিযুক্ত হয়, যতক্ষণ না আপনি কেবল বুলস দিয়েই এটি করছেন আপনি নিরাপদ। আরও: altdevblogaday.org/2011/04/18/
বোঝার-

1

আপনার স্ট্যাকের ব্যবহারের দিকে নজর রাখুন

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

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