গুরুত্বপূর্ণ পটভূমি পঠন: অ্যাগনার ফগের মাইক্রোয়ার্ক পিডিএফ , এবং সম্ভবত আলরিচ ড্র্রেপার মেমরি সম্পর্কে প্রতিটি প্রোগ্রামারকে কী জানা উচিত । এর অন্যান্য লিঙ্কগুলিও দেখুনএক্স 86ট্যাগ উইকি, বিশেষত ইন্টেলের অপ্টিমাইজেশান ম্যানুয়াল এবং ডেভিড ক্যান্টারের হাসওয়েল মাইক্রোআরকিটেকচারের বিশ্লেষণ, ডায়াগ্রাম সহ ।
খুব শীতল কার্যভার; আমি যেগুলি দেখেছি তার থেকে অনেক বেশি ভালো যেখানে শিক্ষার্থীদের কিছু কোডের জন্য অনুকূলকরণ করতে বলা হয়েছিলgcc -O0
, এমন কৌশলগুলি শিখেছে যা বাস্তব কোডে কিছু যায় আসে না। এই ক্ষেত্রে, আপনাকে সিপিইউ পাইপলাইন সম্পর্কে শিখতে এবং এটি কেবল অন্ধ অনুমান না করে আপনার ডি-অপ্টিমাইজেশান প্রচেষ্টা পরিচালনার জন্য ব্যবহার করতে বলা হচ্ছে। এইটির সবচেয়ে মজার অংশটি হ'ল উদ্দেশ্যমূলক কুৎসা নয়, "হতাশার অক্ষমতা" দিয়ে প্রতিটি হতাশাকে ন্যায্যতা প্রদান করা।
অ্যাসাইনমেন্ট শব্দের সাথে কোড এবং কোড :
এই কোডের জন্য উয়ার্ক-নির্দিষ্ট বিকল্পগুলি সীমাবদ্ধ। এটা কোনো অ্যারে ব্যবহার করে না, এবং খরচ অনেক কল হয় exp
/ log
গ্রন্থাগার ফাংশন। অধিক বা কম নির্দেশ-স্তরের সমান্তরালতা থাকার কোনও সুস্পষ্ট উপায় নেই এবং লুপ বহনকারী নির্ভরতা শৃঙ্খলা খুব ছোট।
আমি এমন একটি উত্তর দেখতে পছন্দ করব যা নির্ভরতাগুলি পরিবর্তনের জন্য এক্সপ্রেশনগুলি পুনরায় সাজানো থেকে আইএলপি হ্রাস করার জন্য (হতাশাগুলি) হ্রাস করার চেষ্টা করেছিল । আমি চেষ্টা করেছি না।
ইন্টেল স্যান্ডিব্রিজে-পরিবারের সিপিইউগুলি হ'ল আক্রমণাত্মক আউট-অফ-অর্ডার ডিজাইন যা সমান্তরালতা খুঁজে পেতে এবং বিপদগুলি (নির্ভরতা) এড়াতে প্রচুর ট্রানজিস্টর এবং শক্তি ব্যয় করে যা একটি ক্লাসিক আরআইএসসি-অর্ডার পাইপলাইনে ঝামেলা করবে । সাধারণত একমাত্র traditionalতিহ্যবাহী বিপত্তিগুলি এটি ধীর করে দেয় "কা" সত্য "নির্ভরতা যার ফলে থ্রুপুটটি বিলম্বিত করে সীমাবদ্ধ করে।
নাম এবং রেজিস্ট্রেশন করার জন্য রেজিস্টারগুলির জন্য ওয়ার এবং ডাব্লুএডাব্লু বিপত্তিগুলি খুব বেশি সমস্যা নয় । (popcnt
/lzcnt
/বাদেtzcnt
, যাদের মিথ্যা নির্ভরশীলতা রয়েছে তাদের গন্তব্য ইন্টেল সিপিইউগুলিতে , যদিও এটি কেবল লেখার জন্য থাকে ie যেমন: ডাব্লুএইডাব্লু একটি RAW বিপত্তি হিসাবে + রচনা হিসাবে পরিচালিত হচ্ছে)। মেমোরি অর্ডার দেওয়ার জন্য, আধুনিক সিপিইউ অবসর গ্রহণ পর্যন্ত ক্যাশে প্রতিশ্রুতি বিলম্ব করতে স্টোর সারি ব্যবহার করে , ওয়ার ও ডাব্লুডাব্লু বিপত্তিও এড়িয়ে চলে ।
আগাবারের নির্দেশাবলী থেকে পৃথক পৃথকীকরণ কেন হ্যাসওয়েলে কেবল 3 টি চক্র গ্রহণ করে? এফপি ডট প্রোডাক্ট লুপে রেজিস্টার নামকরণ এবং এফএমএ ল্যাটেন্সি গোপন করার বিষয়ে আরও কিছু রয়েছে।
"আই 7" ব্র্যান্ড-নামটি নেহালেম ( কোর 2 এর উত্তরসূরি) এর সাথে প্রবর্তিত হয়েছিল এবং কিছু ইন্টেল ম্যানুয়াল এমনকি "কোর আই 7" এমনকি নেহালেমকে বোঝায় বলে মনে করে, তবে তারা স্যান্ডিব্রিজ এবং পরবর্তীকালে মাইক্রোআরকিটেকচারগুলির জন্য "আই 7" ব্র্যান্ডিং রেখেছিল । এসবিবি হ'ল পি-পরিবারটি একটি নতুন প্রজাতিতে পরিণত হয়েছিল, এসএনবি-পরিবার । বিভিন্ন উপায়ে, স্যান্ডডিব্রিজের চেয়ে পেন্টিয়াম তৃতীয়ের সাথে নেহালেমের বেশি মিল রয়েছে (যেমন, রেজিস্টার রিড স্টল এবং আরওবি-রিড স্টলগুলি এসএনবি-তে ঘটে না, কারণ এটি একটি ফিজিক্যাল রেজিস্টার ফাইল ব্যবহার করে পরিবর্তিত হয়েছে Also এছাড়াও একটি উওপ ক্যাশে এবং একটি আলাদা অভ্যন্তরীণ) ইউওপ ফর্ম্যাট)। "I7 আর্কিটেকচার" শব্দটি কার্যকর নয়, কারণ এটি নেহালেমের সাথে স্নিবি-পরিবারকে গোষ্ঠীভুক্ত করার পক্ষে কিছুটা বোঝা যায় তবে কোর 2 নয়। (যদিও একাধিক কোর একসাথে সংযোগ করার জন্য নেহালেম শেয়ার্ড ইনক্লুসিভ এল 3 ক্যাশে আর্কিটেকচার প্রবর্তন করেছিলেন। এছাড়াও জিপিইউগুলিকেও সমন্বিত করেছেন। তাই চিপ-লেভেল, নামকরণটি আরও অর্থবোধ করে makes
ডাইবোলিকাল অক্ষমতার ন্যায্যতা দিতে পারে এমন ভাল ধারণাগুলির সংক্ষিপ্তসার
এমনকি ডায়াবলিকভাবে অক্ষমও স্পষ্টত অকেজো কাজ বা একটি অসীম লুপ যুক্ত করার সম্ভাবনা নেই, এবং সি ++ / বুস্ট ক্লাসগুলির সাথে একটি জগাখিচুড়ি করা কার্যনির্বাহনের সুযোগের বাইরে।
- একক ভাগ করা
std::atomic<uint64_t>
লুপের কাউন্টার সহ একাধিক থ্রেড , যাতে সঠিক মোট সংখ্যা পুনরাবৃত্তি ঘটে happen পারমাণবিক uint64_t এর সাথে বিশেষত খারাপ -m32 -march=i586
। বোনাস পয়েন্টগুলির জন্য, এটি বিভ্রান্ত করার ব্যবস্থা করুন এবং অসম বিভাজন (4: 4 নয়) দিয়ে একটি পৃষ্ঠা সীমা অতিক্রম করুন।
- কিছু অন্যান্য অ-পারমাণবিক পরিবর্তনশীল -> মেমরি-অর্ডার ভুল অনুমানের পাইপলাইন সাফ করার পাশাপাশি অতিরিক্ত ক্যাশে মিস করার জন্য মিথ্যা ভাগ করে নেওয়া ।
-
এফপি ভেরিয়েবলগুলি ব্যবহার না করে সাইন বিটটি ফ্লিপ করতে 0x80 এর সাথে হাই বাইটটি এক্সওআর করুন, যার ফলে স্টোর-ফরওয়ার্ডিং স্টলগুলি হয় ।
- প্রতিটি পুনরাবৃত্তিকে স্বাধীনভাবে সময় দিন, তার চেয়েও ভারী কিছু
RDTSC
। যেমন CPUID
/ RDTSC
অথবা একটি সময় ফাংশন যা একটি সিস্টেম কল করে। ক্রমিক নির্দেশাবলী সহজাতভাবে পাইপলাইন-বন্ধুত্বপূর্ণ।
- ধ্রুবক দ্বারা তাদের পারস্পরিক ক্রিয়াকলাপ ("পড়ার স্বাচ্ছন্দ্যের জন্য") দ্বারা ভাগ করে নিন। ডিভি ধীর এবং সম্পূর্ণ পাইপলাইন করা হয় না।
- এভিএক্স (সিমডি) দিয়ে গুণ / স্কয়ারটি ভেক্টরাইজ করুন, তবে
vzeroupper
স্কেলার ম্যাথ-লাইব্রেরি exp()
এবং log()
ফাংশনগুলিতে কল করার আগে ব্যবহার করতে ব্যর্থ হন , যার ফলে AVX <-> এসএসই রূপান্তর স্টল রয়েছে ।
- আরএনজি আউটপুট কোনও লিঙ্কযুক্ত তালিকায় বা অ্যারেতে সংরক্ষণ করুন যা আপনি ক্রম ছাড়িয়ে যান। প্রতিটি পুনরাবৃত্তির ফলাফলের জন্য একই, এবং শেষে সমষ্টি।
এছাড়াও এই উত্তরে কভার করা হয়েছে তবে সংক্ষিপ্তসার থেকে বাদ দেওয়া হয়েছে: প্রস্তাবনাগুলি যে কোনও পাইপলাইনযুক্ত সিপিইউতে ঠিক তত ধীর হবে, বা এটি ডায়াবোলিকাল অক্ষমতার পরেও ন্যায়সঙ্গত বলে মনে হয় না। উদাহরণস্বরূপ অনেকগুলি জিম্প-দ্য-সংকলক ধারণাগুলি স্পষ্টতই পৃথক / আরও খারাপ asm উত্পাদন করে।
মাল্টি-থ্রেড খারাপভাবে
গতি লাভের চেয়ে বেশি ওভারহেড সহ খুব কম পুনরাবৃত্তির সাথে মাল্টি-থ্রেড লুপগুলিতে ওপেনএমপি ব্যবহার করুন। আপনার মন্টে-কার্লো কোডটিতে আসলে একটি স্পিডআপ পেতে যথেষ্ট সমান্তরালতা রয়েছে, যদিও, এসএসপি। আমরা যদি প্রতিটি পুনরাবৃত্তিটি ধীর করে তুলতে সফল হই। (প্রতিটি থ্রেড একটি আংশিক গণনা payoff_sum
করে, শেষে যুক্ত করা হয়)। #omp parallel
সেই লুপটিতে সম্ভবত একটি অপ্টিমাইজেশন হবে, কোনও হতাশাই নয়।
মাল্টি-থ্রেড তবে উভয় থ্রেডকে একই লুপের কাউন্টারটি ভাগ করতে বাধ্য করুন ( atomic
ইনক্রিমেন্ট সহ যাতে পুনরাবৃত্তির মোট সংখ্যা সঠিক)। এটি ডায়াবলিকভাবে যৌক্তিক বলে মনে হয়। এর অর্থ static
লুপের কাউন্টার হিসাবে ভেরিয়েবল ব্যবহার করা । এটি atomic
লুপ কাউন্টারগুলির ব্যবহারকে ন্যায়সঙ্গত করে এবং প্রকৃত ক্যাশে-লাইন পিং-পংিং তৈরি করে (যতক্ষণ না থ্রেডগুলি হাইপারথ্রেডিংয়ের সাথে একই শারীরিক মূলের উপরে না চলে; এটি তত ধীরে নাও হতে পারে )) যাইহোক, এটি অন-বিতর্কিত মামলার তুলনায় অনেক ধীর lock inc
। এবং lock cmpxchg8b
পরমাণুগতভাবে বৃদ্ধির জন্য uint64_t
32 বিবিটি সিস্টেমে প্রার্থী হওয়াটিকে একটি পারমাণবিক হার্ডওয়্যারকে আরবিট্রেট করার পরিবর্তে একটি লুপে আবার চেষ্টা করতে হবে inc
।
মিথ্যা ভাগ করে নেওয়াও তৈরি করুন , যেখানে একাধিক থ্রেডগুলি তাদের ব্যক্তিগত ডেটা (যেমন আরএনজি অবস্থা) একই ক্যাশে লাইনের বিভিন্ন বাইটে রাখে। (এটি দেখার জন্য পারফেক্ট কাউন্টারগুলি সহ এটি সম্পর্কে ইন্টেল টিউটোরিয়াল) । এটির জন্য একটি মাইক্রোআরকিটেকচার-নির্দিষ্ট দিক রয়েছে : ইন্টেল সিপিইউগুলি মেমরির ভুল অর্ডার না হওয়ার বিষয়ে অনুমান করে এবং কমপক্ষে পি 4 এ সনাক্ত করার জন্য একটি মেমরি-অর্ডার মেশিন-ক্লিয়ার পারফ ইভেন্ট রয়েছে । জরিমানা হাসওয়েলে এত বড় নাও হতে পারে। যেহেতু এই লিঙ্কটি নির্দেশ করে, একটি lock
এড নির্দেশ অনুমান করে যে এটি ঘটবে, ভুল অনুমান এড়িয়ে চলবে। একটি সাধারণ লোড অনুমান করে যে অন্যান্য কোরগুলি যখন লোডটি সঞ্চালিত হয় এবং প্রোগ্রামের ক্রমে অবসর নেয় তখন এর মধ্যে একটি ক্যাশে লাইনকে অকার্যকর করে না (যদি না আপনি ব্যবহারpause
)। lock
এড নির্দেশাবলী ছাড়া সত্য ভাগ করে নেওয়া সাধারণত একটি বাগ। পারমাণবিক কেসের সাথে একটি অ-পারমাণবিক ভাগযুক্ত লুপ কাউন্টারটির তুলনা করা আকর্ষণীয় হবে। সত্যিই হতাশার জন্য, ভাগ করা পারমাণবিক লুপের কাউন্টার রাখুন এবং অন্য কোনও ভেরিয়েবলের জন্য একই বা ভিন্ন ক্যাশে লাইনে মিথ্যা ভাগ করে নেওয়ার কারণ ঘটায়।
এলোমেলোভাবে uarch- নির্দিষ্ট ধারণা:
আপনি যদি কোনও অনির্দেশ্য শাখা চালু করতে পারেন তবে কোডটি যথেষ্ট পরিমাণে হতাশ হবে। আধুনিক x86 সিপিইউতে বেশ দীর্ঘ পাইপলাইন রয়েছে, সুতরাং একটি ভুল অনুমানের জন্য ~ 15 চক্রের ব্যয় হয় (যখন ইউওপ ক্যাশে থেকে চলমান)।
নির্ভরশীল শৃঙ্খলা:
আমি মনে করি এটি কার্যভারের একটি উদ্দেশ্যযুক্ত অংশ ছিল।
একাধিক সংক্ষিপ্ত নির্ভরশীল শৃঙ্খলার পরিবর্তে একটি দীর্ঘ নির্ভরশীল শৃঙ্খলা রয়েছে এমন ক্রিয়াকলাপগুলির ক্রম চয়ন করে নির্দেশ-স্তরের সমান্তরালতা কাজে লাগানোর সিপিইউর ক্ষমতাকে পরাস্ত করুন। কম্পাইলাররা এফপি গণনার জন্য ক্রিয়াকলাপগুলি পরিবর্তনের অনুমতি দেয় না আপনি যদি না ব্যবহার করেন তবে -ffast-math
এটি ফলাফল পরিবর্তন করতে পারে (নীচে আলোচনা করা হয়েছে)।
এটি কার্যকরভাবে কার্যকর করতে একটি লুপ বহনকারী নির্ভরতা শৃঙ্খলার দৈর্ঘ্য বৃদ্ধি করুন। কিছুই স্পষ্টতই লাফিয়ে উঠবে না, যদিও: লিখিত লুপগুলিতে খুব স্বল্প লুপ বহনকারী নির্ভরতা শৃঙ্খলা রয়েছে: কেবল একটি এফপি যোগ করুন। (3 চক্র) একাধিক পুনরাবৃত্তির একযোগে তাদের গণনাগুলি থাকতে পারে, কারণ তারা payoff_sum +=
পূর্ববর্তী পুনরাবৃত্তির শেষে খুব ভাল শুরু করতে পারে । ( log()
এবং সমান্তরাল সন্ধানের জন্য হাসওলের আউট-অফ-অর্ডার উইন্ডোরexp
চেয়ে অনেকগুলি নির্দেশনা নিন তবে আরওবি আকার = 192 ফিউজড-ডোমেন উফস, এবং শিডিয়ুলার আকার = 60 অব্যবহৃত-ডোমেন উফস। বর্তমান পুনরাবৃত্তির কার্যকর করার সাথে সাথে পরবর্তী পুনরাবৃত্তি থেকে ইস্যু করার জন্য নির্দেশের জন্য জায়গা তৈরি করার পর্যাপ্ত অগ্রগতি হওয়ার সাথে সাথে, পুরানো নির্দেশাবলী কার্যকরকারী ইউনিটগুলি ছেড়ে যাওয়ার পরে এর যে কোনও অংশে যার ইনপুট প্রস্তুত রয়েছে (যেমন স্বাধীন / পৃথক ডিপ চেইন) কার্যকর করা শুরু করতে পারে ফ্রি (উদাঃ কারণ এরা থ্রুপুট নয়, বিলম্বের সাথে বাধা রয়েছে))।
আরএনজি রাষ্ট্রটি অবশ্যই অবশ্যই এর চেয়ে দীর্ঘতর লুপ বহনকারী নির্ভরতা শৃঙ্খলা হবে addps
।
ধীর / আরও এফপি ক্রিয়াকলাপগুলি ব্যবহার করুন (যেমন আরও বিভাগ):
০.০ দিয়ে ভাগ করার পরিবর্তে ২.০ দ্বারা ভাগ করুন এবং আরও কিছু। এফপি গুণমানটি ইন্টেল ডিজাইনে ভারী পাইপলাইনযুক্ত, এবং হাসওলে এবং পরবর্তী সময়ে প্রতি 0.5c থ্রুটপুট রয়েছে। এফপি divsd
/ divpd
কেবলমাত্র আংশিক পাইপলাইনযুক্ত । (যদিও স্কাইলেকের প্রতি 4 divpd xmm
গ থ্রুটপুটটিতে একটি চিত্তাকর্ষক একটি রয়েছে , 13-14 সি ল্যাটেন্সি সহ, বনাম নেহালেম (7-22 সি) তে পাইপলাইন করা হয়নি)।
do { ...; euclid_sq = x*x + y*y; } while (euclid_sq >= 1.0);
স্পষ্টতই দূরত্ব জন্য পরীক্ষা করছে, তাই পরিষ্কারভাবে এটি সঠিক হবে sqrt()
এটা। : পি (এর sqrt
চেয়ে ধীর গতির div
)।
@ পল ক্লেটন এর পরামর্শ অনুসারে, সহযোগী / বিতরণ সমতুল্য সহ পুনর্লিখনের এক্সপ্রেশনগুলি আরও কাজ প্রবর্তন করতে পারে (যতক্ষণ না আপনি সংকলকটিকে -ffast-math
পুনরায় অনুকূলকরণের অনুমতি দেওয়ার জন্য ব্যবহার করবেন না )। (exp(T*(r-0.5*v*v))
হয়ে যেতে পারে exp(T*r - T*v*v/2.0)
। মনে রাখবেন যে আসল সংখ্যার গাণিতিক সংঘবদ্ধ হলেও, ভাসমান পয়েন্ট গণিতটি নয় , এমনকি ওভারফ্লো / এনএএন বিবেচনা না করেও (কারণ -ffast-math
এটি ডিফল্টরূপে নেই)। খুব লোমযুক্ত নীচের পরামর্শের জন্য পলের মন্তব্য দেখুন pow()
।
আপনি গণনার খুব ছোট নম্বরে আনুপাতিক হারে কমান করতে পারেন, তারপর FP গণিত অপস নেওয়া মাইক্রো-থেকে ফাঁদে ~ 120 অতিরিক্ত চক্র দুটি স্বাভাবিক সংখ্যার উপর একটি অপারেশন denormal উত্পাদন করে । সঠিক সংখ্যা এবং বিশদ জানতে অ্যাগনার ফগের মাইক্রোয়ার্ক পিডিএফ দেখুন। আপনার পক্ষে প্রচুর বহুগুণ রয়েছে বলে এটি অসম্ভব, সুতরাং স্কেল ফ্যাক্টরটি স্কোয়ার হয়ে সমস্ত পথে 0.0 এ প্রবাহিত হবে। আমি অযোগ্যতার (এমনকি ডায়াবোলিকাল) সাথে প্রয়োজনীয় স্কেলিংকে ন্যায়সঙ্গত করার কোনও উপায় দেখতে পাচ্ছি না, কেবল ইচ্ছাকৃত কুৎসা।
আপনি যদি ইন্টার্নিক্স ব্যবহার করতে পারেন ( <immintrin.h>
)
movnti
ক্যাশে থেকে আপনার ডেটা উচ্ছেদ করতে ব্যবহার করুন । ডায়াবলিকাল: এটি নতুন এবং দুর্বলভাবে অর্ডারযুক্ত, যাতে সিপিইউ এটি দ্রুত চালানো উচিত, তাই না? অথবা সেই ক্ষেত্রে লিঙ্কযুক্ত প্রশ্নটি দেখুন যেখানে কেউ ঠিক এমনটি করার ঝুঁকিতে পড়েছিল (ছড়িয়ে ছিটিয়ে থাকা লেখাগুলির জন্য যেখানে কেবলমাত্র কয়েকটি অবস্থান গরম ছিল)। clflush
বিদ্বেষ ছাড়া সম্ভবত অসম্ভব।
বাইপাস বিলম্বের কারণ হিসাবে এফপি গণিত ক্রিয়াকলাপগুলির মধ্যে পূর্ণসংখ্যার শাফলগুলি ব্যবহার করুন।
যথাযথ ব্যবহার না করে SSE এবং AVX নির্দেশাবলী মিক্সিং vzeroupper
প্রাক Skylake মধ্যে কারণ বৃহৎ স্টল (এবং একটি ভিন্ন শাস্তি Skylake মধ্যে )। এমনকি এটি ছাড়াও, ভেক্টরাইজিং খারাপভাবে স্কেলারের চেয়েও খারাপ হতে পারে (একবারে 4 মন্টি-কার্লো পুনরাবৃত্তির জন্য একবারে 256 বি ভেক্টর যুক্ত / সাব / মুল / ডিভি / স্কয়ার্ট ক্রিয়াকলাপগুলি সংরক্ষণের চেয়ে বেশি চক্রগুলি ভেক্টরগুলিতে / বাইরে স্ফালিং ডেটা ব্যয় করে) । অ্যাড / সাব / মুল এক্সিকিউশন ইউনিট পুরোপুরি পাইপলাইনযুক্ত এবং পূর্ণ প্রশস্ত, তবে 256 বি ভেক্টরগুলিতে ডিভ এবং স্কয়ার্ট 128 বি ভেক্টর (বা স্কেলার) হিসাবে তত দ্রুত হয় না, তাই স্পিডআপ নাটকীয় নয়double
।
exp()
এবং log()
হার্ডওয়্যার সমর্থন নেই, সুতরাং সেই অংশটির জন্য ভ্যাক্টর উপাদানগুলি স্কেলারে ফিরে বের করা এবং পৃথকভাবে লাইব্রেরির ফাংশন কল করা দরকার, তারপরে ফলাফলগুলি আবার কোনও ভেক্টরে বদলে নেওয়া। লিবিএম সাধারণত কেবল এসএসই 2 ব্যবহারের জন্য সংকলিত হয়, সুতরাং স্কেলার ম্যাথের নির্দেশাবলীর লিগ্যাসি-এসএসই এনকোডিংগুলি ব্যবহার করবে। যদি আপনার কোডটি প্রথমে 256b ভেক্টর ব্যবহার করে এবং কল exp
না করে vzeroupper
তবে আপনি স্টল করুন। ফিরে আসার পরে, একটি এভিএক্স -128 নির্দেশ vmovsd
পরবর্তী স্ট্রাক্টর এলিমেন্টটিকে একটি আর্গ হিসাবে স্থির করতে পছন্দ করে exp
। এবং তারপর exp()
আবার যখন এটি একটি SSE নির্দেশ চালায় ফাঁকি হবে। এই প্রশ্নটিতে ঠিক এটি ঘটেছে , যার ফলে 10x মন্দা দেখা দেয়। (ধন্যবাদ @ জেডবোসন)।
এই কোডটির জন্য ইন্টেলের ম্যাথ ম্যাথ লাইব বনাম গ্লিবিসি নিয়ে নাথন কুর্জের পরীক্ষা-নিরীক্ষাও দেখুন । ভবিষ্যতের গ্লিবিসি আসবে ভেক্টরাইজড বাস্তবায়ন ইত্যাদির সাথে ।exp()
যদি প্রাক-আইভিবি, বা এসপিএসকে লক্ষ্য করে তোলা হয়। নেহালেম, 16 বিট বা 8 বিট ক্রিয়াকলাপের পরে 32 বিট বা 64 বিট ক্রিয়াকলাপ সহ আংশিক-নিবন্ধক স্টলগুলির জন্য জিসিসি পাওয়ার চেষ্টা করুন। বেশিরভাগ ক্ষেত্রে, জিসিসি movzx
8 বা 16 বিটের ক্রিয়াকলাপের পরে ব্যবহার করবে , তবে এখানে একটি কেস রয়েছে যেখানে জিসিসি পরিবর্তন করে ah
এবং তারপরে পাঠ করেax
(ইনলাইন) asm সহ:
(ইনলাইন) asm এর সাহায্যে আপনি ইউওপ ক্যাশেটি ভেঙে ফেলতে পারেন: একটি 32B কোডের অংশ যা তিনটি 6uop ক্যাশে লাইনে ফিট করে না the অভ্যন্তরীণ লুপের অভ্যন্তরে একটি শাখার টার্গেটে দু'জন দীর্ঘ s এর পরিবর্তে ALIGN
অনেকগুলি একক বাইট ব্যবহার করে অযোগ্য tent বা লেবেলের পরে অ্যালাইনমেন্টের প্যাডিংয়ের পরিবর্তে রাখুন instead : পি এটি কেবল তখনই বিবেচনা করে যদি সম্মুখভাগটি কোনও বাধা হয়, যা আমরা যদি বাকী কোডটি অনুমান করতে সফল হই তবে তা হবে না।nop
nop
পাইপলাইন ক্লিয়ারস (ওরফে মেশিন-নিউকস) ট্রিগার করতে স্ব-পরিবর্তনকারী কোড ব্যবহার করুন।
8 বিটে ফিট করার জন্য খুব বড় ইমডিয়েটসের সাথে 16 বিট নির্দেশাবলীর এলসিপি স্টলগুলি কার্যকর হওয়ার সম্ভাবনা নেই। এসএনবিতে ইউওপ ক্যাশে এবং এর পরে আপনি কেবল একবার ডিকোড পেনাল্টি প্রদান করবেন। নেহালেমে (প্রথম আই 7), এটি এমন লুপের জন্য কাজ করতে পারে যা 28 টি লুপ বাফারে ফিট করে না। gcc কখনও কখনও এই জাতীয় নির্দেশাবলী তৈরি -mtune=intel
করতে পারে এমনকি এমনকি এটি কখন একটি 32 বিট নির্দেশ ব্যবহার করতে পারে।
সময় নির্ধারণের জন্য একটি সাধারণ প্রতিমা হ'ল CPUID
(সিরিয়ালাইজ করা) তখনRDTSC
। পূর্ববর্তী নির্দেশাবলীর সাথে পুনরায় সাজানো হয়নি তা নিশ্চিত করার জন্য প্রতিটি পুনরাবৃত্তির আলাদাভাবে সময় CPUID
/ RDTSC
যা সময়কে অনেকটাRDTSC
ধীর করে দেয় । (বাস্তব জীবনে, সময়ের স্মার্ট উপায় হ'ল প্রতিটি পুনরাবৃত্তি এক সাথে আলাদা করে সময় দেওয়ার পরিবর্তে সেগুলি যুক্ত করা))
প্রচুর ক্যাশে মিস এবং অন্যান্য স্মৃতিশক্তি হ্রাসের কারণ
আপনার union { double d; char a[8]; }
কিছু ভেরিয়েবলের জন্য একটি ব্যবহার করুন । কেবলমাত্র একটি বাইটে সংকীর্ণ স্টোর (বা পড়ুন-সংশোধন করুন-লিখন) করে স্টোর-ফরওয়ার্ডিং স্টলের কারণ দিন । (এই উইকি নিবন্ধটি লোড / স্টোরের সারিগুলির জন্য প্রচুর পরিমাণে অন্যান্য মাইক্রো আঞ্চলিক বিষয়াদিও অন্তর্ভুক্ত করে)। উদাহরণস্বরূপ অপারেটরের পরিবর্তে কেবল উচ্চ বাইটে এক্সওআর 0x80 ব্যবহারের চিহ্নটি ফ্লিপ করুনdouble
-
। ডায়াবলিকভাবে অক্ষম বিকাশকারী শুনে থাকতে পারে যে এফপি পূর্ণসংখ্যার চেয়ে ধীর হয় এবং এভাবে পূর্ণসংখ্যার অপ্স ব্যবহার করে যতটা সম্ভব চেষ্টা করার চেষ্টা করে। (এসএসই রেজিস্টারগুলিতে এফপি গণিতকে লক্ষ্য করে একটি খুব ভাল সংকলক সম্ভবত এটি একটিতে সংকলন করতে পারেxorps
অন্য এক্সএমএম রেজিস্টারে একটি ধ্রুবক সহ, তবে এক্স ৮ for-এর জন্য এটি কেবল ভয়ঙ্কর নয় একমাত্র উপায় হ'ল যদি সংকলক বুঝতে পারে যে এটি মানটিকে অবহেলা করছে এবং পরের যোগটিকে একটি বিয়োগের সাথে প্রতিস্থাপন করে))
volatile
আপনি যদি সংকলকটি ব্যবহার করছেন -O3
না এবং ব্যবহার না করছেন তবে ব্যবহার করুন std::atomic
, কম্পাইলারটিকে সমস্ত জায়গাতেই ਅਸਲে সঞ্চয় / পুনরায় লোড করতে বাধ্য করতে। গ্লোবাল ভেরিয়েবলগুলি (স্থানীয়দের পরিবর্তে) কিছু স্টোর / পুনরায় লোড করার জন্য বাধ্য করবে, তবে সি ++ মেমরি মডেলের দুর্বল ক্রমটির জন্য সমস্ত সময় স্মৃতিতে স্পিল / পুনরায় লোড করার সংকলকটির প্রয়োজন হয় না।
একটি বড় কাঠামোর সদস্যদের সাথে স্থানীয় যুদ্ধগুলি প্রতিস্থাপন করুন, যাতে আপনি মেমরি লেআউটটি নিয়ন্ত্রণ করতে পারেন।
প্যাডিংয়ের জন্য স্ট্রাক্টে অ্যারেগুলি ব্যবহার করুন (এবং তাদের অস্তিত্বের ন্যায্যতা জানাতে এলোমেলো সংখ্যার সঞ্চয় করা)।
আপনার মেমরির বিন্যাসটি চয়ন করুন যাতে সমস্ত 1 এল 1 ক্যাশে একই "সেট" এর আলাদা লাইনে যায় । এটি কেবলমাত্র 8-ওয়ে সহকারী, অর্থাত প্রতিটি সেটে 8 টি "উপায়" রয়েছে। ক্যাশে লাইনগুলি 64 বি।
আরও ভাল, জিনিসগুলিকে ঠিক 4096B আলাদা করে রাখুন, যেহেতু লোডগুলির বিভিন্ন পৃষ্ঠাগুলিতে স্টোরগুলিতে একটি মিথ্যা নির্ভরতা থাকে তবে একই পৃষ্ঠায় একই অফসেট থাকে । আক্রমণাত্মক আউট-অফ-অর্ডার সিপিইউগুলি ফলাফলগুলি পরিবর্তন না করে কখন লোড এবং স্টোরগুলিকে পুনরায় সাজানো যায় তা নির্ধারণের জন্য মেমরি ডিসেমবিগুয়েগেশন ব্যবহার করে এবং ইন্টেলের বাস্তবায়নে ভুয়া-পজিটিভ রয়েছে যা লোডগুলি তাড়াতাড়ি শুরু হতে বাধা দেয়। সম্ভবত তারা কেবল অফসেট পৃষ্ঠার নীচে বিটগুলি চেক করে রাখে, যাতে টিএলবি একটি ভার্চুয়াল পৃষ্ঠা থেকে একটি ভৌত পৃষ্ঠায় উচ্চ বিট অনুবাদ করার আগে চেকটি শুরু হতে পারে। অ্যাগনারের গাইডের পাশাপাশি স্টিফেন ক্যাননের একটি উত্তর এবং একই প্রশ্নে @ ক্রজি গ্লিউয়ের উত্তরের শেষের একটি অংশ দেখুন। (অ্যান্ডি গ্লিউ ছিলেন ইন্টেলের মূল পি 6 মাইক্রোর্কিটেকচারের অন্যতম স্থপতি।)
__attribute__((packed))
আপনাকে ভেরিয়েবলগুলি ভুল-প্রান্তিককরণ করতে ব্যবহার করুন যাতে সেগুলি ক্যাশে-লাইন বা পৃষ্ঠার সীমানা স্প্যান করে। (সুতরাং একটি লোডের double
দুটি ক্যাশে-লাইন থেকে ডেটা প্রয়োজন)। ক্যাশ লাইন এবং পৃষ্ঠা লাইনগুলি অতিক্রম করার পরে, মিসেলাইনযুক্ত লোডগুলির কোনও ইনটেল আই 7 উর্চে কোনও জরিমানা নেই। ক্যাশে-লাইন বিভাজনগুলি এখনও অতিরিক্ত চক্র নেয় । স্কাইলেক নাটকীয়ভাবে পৃষ্ঠা বিভক্ত লোডের জন্য 100 থেকে 5 চক্রের জন্য পেনাল্টি হ্রাস করে । (বিভাগ 2.1.3) । সমান্তরালে দুটি পৃষ্ঠা হাঁটাতে সক্ষম হওয়ার সাথে সম্পর্কিত।
একটিতে পৃষ্ঠা-বিভক্ত atomic<uint64_t>
হওয়া উচিত সবচেয়ে খারাপ ক্ষেত্রে , যেমন। যদি এটি একটি পৃষ্ঠায় 5 বাইট এবং অন্য পৃষ্ঠায় 3 বাইট, বা 4: 4 ব্যতীত অন্য কোনও কিছু হয়। এমনকি মাঝখানে নীচে বিভক্ত হওয়া কিছু উয়ারচ, আইআইআরসি-তে 16 বি ভেক্টর সহ ক্যাশে-লাইন বিভাজনের জন্য আরও কার্যকর। alignas(4096) struct __attribute((packed))
আরএনজি ফলাফলের জন্য স্টোরেজের জন্য একটি অ্যারে সহ সমস্ত কিছু (অবশ্যই স্থান বাঁচাতে) রাখুন । কাউন্টার ব্যবহার করার আগে uint8_t
বা uint16_t
কিছু ব্যবহার করে বিভ্রান্তি অর্জন করুন ।
আপনি যদি সূচকযুক্ত ঠিকানাগুলি ব্যবহার করতে সংকলকটি পেতে পারেন তবে এটি ইউওপ মাইক্রো-ফিউশনকে পরাস্ত করবে । হয়তো এর সাহায্যে #define
সাধারণ স্কেলার ভেরিয়েবলগুলি প্রতিস্থাপন করতে my_data[constant]
।
যদি আপনি অতিরিক্ত স্তরের ইন্ডিয়ারেশনের পরিচয় দিতে পারেন, তাই লোড / স্টোর ঠিকানাগুলি প্রাথমিকভাবে জানা যায় না, এটি আরও হতাশ করতে পারে।
অ-সঙ্গত ক্রমে ট্র্যাভার্স অ্যারে
আমি মনে করি আমরা প্রথম স্থানে অ্যারে প্রবর্তনের জন্য অযোগ্য যুক্তিসঙ্গততা নিয়ে আসতে পারি: এটি আমাদের এলোমেলো সংখ্যা ব্যবহার থেকে এলোমেলো সংখ্যা জেনারেশনকে আলাদা করতে দেয়। প্রতিটি পুনরাবৃত্তির ফলাফলগুলি একটি অ্যারেতেও সংরক্ষণ করা যেতে পারে, পরবর্তীকালে সংক্ষিপ্ত করা যেতে পারে (আরও ডায়াবোলিকাল অক্ষমতা সহ)।
"সর্বোচ্চ র্যান্ডমনেস" এর জন্য, আমরা এলোমেলোভাবে অ্যারেতে নতুন এলোমেলো সংখ্যা লিখতে একটি থ্রেড লুপিং করতে পারি। এলোমেলো সংখ্যা গ্রাসকারী থ্রেড এলোমেলো সংখ্যা লোড করার জন্য একটি এলোমেলো সূচক তৈরি করতে পারে। (এখানে কিছু মেক-ওয়ার্ক রয়েছে, তবে মাইক্রোআরআরেক্টিচার্যালি এটি লোড-অ্যাড্রেসগুলি তাড়াতাড়ি জানাতে সহায়তা করে যাতে লোড হওয়া ডেটার প্রয়োজন হওয়ার আগে কোনও সম্ভাব্য লোডের প্রবণতা সমাধান করা যায়)) বিভিন্ন কোরে একটি পাঠক এবং লেখক থাকায় স্মৃতি-ক্রমবর্ধমান ভুল হতে পারে -স্পেসুলেশন পাইপলাইন ক্লিয়ার (ভুয়া-ভাগাভাগির ক্ষেত্রে আগে আলোচনা করা হয়েছে)।
সর্বাধিক হতাশার জন্য, 4096 বাইটের (অর্থাৎ 512 ডাবল) স্ট্রাইড সহ আপনার অ্যারের উপরে লুপ করুন। যেমন
for (int i=0 ; i<512; i++)
for (int j=i ; j<UPPER_BOUND ; j+=512)
monte_carlo_step(rng_array[j]);
সুতরাং অ্যাক্সেস প্যাটার্নটি 0, 4096, 8192, ...,
8, 4104, 8200, ...
16, 4112, 8208, ...
double rng_array[MAX_ROWS][512]
@ জেস্পারজুহেল পরামর্শ দিয়েছিলেন যে, আপনি একটি ভুলভাবে ক্রমে 2 ডি অ্যারে অ্যাক্সেসের জন্য পাবেন (অভ্যন্তরীণ লুপের মধ্যে একটি সারির মধ্যে কলামগুলির পরিবর্তে সারিগুলির উপর দিয়ে লুপিং করুন)। ডায়াবলিকাল অক্ষমতা যদি এর মতো মাত্রাগুলি সহ একটি 2 ডি অ্যারের ন্যায্যতা প্রমাণ করতে পারে তবে বাগানের বিভিন্ন রিয়েল-ওয়ার্ল্ড অক্ষমতা সহজেই ভুল অ্যাক্সেসের ধরণ দিয়ে লুপিংকে ন্যায়সঙ্গত করে। বাস্তব জীবনে বাস্তব কোডে এটি ঘটে।
যদি অ্যারেটি বড় না হয় তবে একই কয়েকটি পৃষ্ঠা পুনরায় ব্যবহারের পরিবর্তে বিভিন্ন ভিন্ন পৃষ্ঠা ব্যবহার করার প্রয়োজনে লুপের সীমাগুলি সামঞ্জস্য করুন। হার্ডওয়্যার প্রিফেচিং পৃষ্ঠাতে জুড়ে (পাশাপাশি / মোটেও) কাজ করে না। প্রিফেটচার প্রতিটি পৃষ্ঠার মধ্যে একটি ফরোয়ার্ড এবং একটি পশ্চাৎপদ প্রবাহ ট্র্যাক করতে পারে (যা এখানে ঘটে তাই) তবে মেমরির ব্যান্ডউইথ যদি ইতিমধ্যে প্রিফেচ-এর সাথে স্যাচুরেট না হয় তবে কেবলমাত্র এটিতে কাজ করবে।
এটি পৃষ্ঠাগুলি একটি বিশাল পৃষ্ঠায় একীভূত না করা হলে এটি লিনাক্স সুবিধাজনকভাবে বেনামে (ফাইল-ব্যাক নয়) বরাদ্দ করার জন্য malloc
/ new
যে ব্যবহারের জন্য বরাদ্দ দেয়) এটিmmap(MAP_ANONYMOUS)
প্রচুর টিএলবি মিস করবে ।
ফলাফলের তালিকা সঞ্চয় করার জন্য কোনও অ্যারের পরিবর্তে, আপনি একটি লিঙ্কযুক্ত তালিকা ব্যবহার করতে পারেন । তারপরে প্রতিটি পুনরাবৃত্তির জন্য পয়েন্টার-চেজিং লোডের প্রয়োজন হবে (পরবর্তী লোডের লোড-ঠিকানার জন্য একটি RAW সত্য নির্ভরতা বিপত্তি)। খারাপ বরাদ্দকারীর সাহায্যে, আপনি ক্যাশে পরাজিত করে মেমরির চারপাশের তালিকা নোডগুলি ছড়িয়ে দিতে পরিচালনা করতে পারেন। ডায়াবোলিক্যালি অক্ষম বরাদ্দকারী সহ, এটি নিজের পৃষ্ঠাটির শুরুতে প্রতিটি নোড রাখতে পারে। (উদাহরণস্বরূপ mmap(MAP_ANONYMOUS)
, পৃষ্ঠাগুলি ভাঙা বা সঠিকভাবে সমর্থন করার জন্য অবজেক্ট মাপগুলি ট্র্যাক না করেই সরাসরি বরাদ্দ করুন free
)।
এগুলি আসলে মাইক্রোআরকিটেকচার-নির্দিষ্ট নয়, পাইপলাইনের সাথে তাদের সামান্য যোগসূত্র রয়েছে (এর বেশিরভাগটি নন-পাইপলাইনযুক্ত সিপিইউতে মন্দাও হবে)।
কিছুটা অফ-টপিক: সংকলকটি আরও খারাপ কোড তৈরি করুন / আরও কাজ করুন:
সর্বাধিক অনুশীলনকারী কোডের জন্য সি ++ 11 std::atomic<int>
এবং std::atomic<double>
ব্যবহার করুন। lock
অন্য থ্রেড থেকে বিতর্ক ছাড়াই এমএফএনসিইএস এবং এড নির্দেশাবলী বেশ ধীর।
-m32
ধীর কোড তৈরি করবে, কারণ x87 কোডটি এসএসই 2 কোডের চেয়ে খারাপ হবে। স্ট্যাক ভিত্তিক 32bit সম্মেলন আহ্বান আরো নির্দেশাবলীর নেয় এবং মত ফাংশন স্ট্যাক এমনকি FP args পাসের exp()
। atomic<uint64_t>::operator++
চালু করার -m32
জন্য একটি lock cmpxchg8B
লুপ (i586) প্রয়োজন। (সুতরাং লুপ কাউন্টারগুলির জন্য এটি ব্যবহার করুন! [অশুভ হাসি])।
-march=i386
হতাশাবোধও করবেন (ধন্যবাদ @ জেস্পার)। এফপি তুলনা fcom
686 এর চেয়ে ধীর fcomi
। প্রাক-586 কোনও পারমাণবিক bit৪ বিট স্টোর সরবরাহ করে না, (কেবল একটি সিএমপিএক্সচাগা যাক), সুতরাং সমস্ত 64৪ বিট অপসটি লিবজিগিসিই atomic
ফাংশন কলগুলিতে সংকলন করে (যা সম্ভবত লক ব্যবহারের পরিবর্তে i686 এর জন্য সংকলিত)। শেষ অনুচ্ছেদে গডবোল্ট কম্পাইলার এক্সপ্লোরার লিঙ্কে এটি ব্যবহার করে দেখুন।
ব্যবহারের long double
/ sqrtl
/ expl
অতিরিক্ত স্পষ্টতা এবং Abis যেখানে যাও sizeof (অতিরিক্ত মন্থরতা জন্য long double
) 10 বা 16 (প্রান্তিককরণ জন্য প্যাডিং সঙ্গে) করা হয়। (IIRC, 64bit উইন্ডোজ ব্যবহারের 8byte long double
সমতূল্য double
। (যাই হোক, লোড / 10byte এর দোকান (80bit) FP operands 4/7 uops, বনাম হয় float
বা double
শুধুমাত্র জন্য প্রতিটি uop 1 গ্রহণ fld m64/m32
/ fst
)। সঙ্গে x87 অত্যাচার long double
পরাজয় স্বয়ংক্রিয় vectorization এমনকি জিসিসি -m64 -march=haswell -O3
।
atomic<uint64_t>
লুপ কাউন্টার ব্যবহার না করে, লুপ কাউন্টার long double
সহ সমস্ত কিছুর জন্য ব্যবহার করুন ।
atomic<double>
সংকলন, তবে পঠন-পরিবর্তন-লেখার ক্রিয়াগুলি +=
এর জন্য সমর্থিত নয় (এমনকি 64৪ বিট পর্যন্ত)। atomic<long double>
কেবলমাত্র পারমাণবিক লোড / স্টোরের জন্য একটি লাইব্রেরি ফাংশন কল করতে হবে। এটি সম্ভবত সত্যিই অদক্ষ, কারণ x86 আইএসএ স্বাভাবিকভাবেই পারমাণবিক 10 বাইট লোড / স্টোরকে সমর্থন করে না এবং লকিং ছাড়াই আমি কেবল ভাবতে পারি ( cmpxchg16b
) 64৪ বিট মোডের প্রয়োজন।
এ -O0
অস্থায়ী Vars করতে অংশের বরাদ্দ আরও দোকান / পুনরায় লোড করা হবে দ্বারা একটি বড় অভিব্যক্তি বিচ্ছেদ। ছাড়া volatile
বা কিছু, এই অপ্টিমাইজেশান সেটিংসের সাথে কোন ব্যাপার না করবে বাস্তব কোডের একটি বাস্তব বিল্ড ব্যবহার করেন।
সি aliasing নিয়ম মেনে অনুমতি char
তাই একটি মাধ্যমে সংরক্ষণকারী ওরফে কিছু char*
আগে বাইট-স্টোরে পর, এমনকি এ / দোকান / রিলোড সবকিছু কম্পাইলার বাহিনী -O3
। (এটি অটো-ভেক্টরাইজিং কোডেরuint8_t
জন্য একটি সমস্যা যা উদাহরণস্বরূপ এর অ্যারেতে চালিত হয় ))
ব্যবহার করে দেখুন uint16_t
লুপ কাউন্টার,, 16bit করতে ছাঁটাই বলপূর্বক সম্ভবত 16bit প্রতীক আকার (সম্ভাব্য স্টল) এবং / অথবা অতিরিক্ত ব্যবহারের মাধ্যমে movzx
নির্দেশাবলী (নিরাপদ)। স্বাক্ষরিত ওভারফ্লো অনির্ধারিত আচরণ , সুতরাং আপনি যদি না ব্যবহার করেন -fwrapv
বা কমপক্ষে -fno-strict-overflow
, স্বাক্ষরযুক্ত লুপ কাউন্টারগুলি প্রতিটি পুনরাবৃত্তিকে পুনরায় সাইন-প্রসারিত করতে হবে না , এমনকি যদি bit৪ বিট পয়েন্টারে অফসেট হিসাবে ব্যবহৃত হয়।
পূর্ণসংখ্যা থেকে float
আবার ফিরে যেতে বাধ্য করুন । এবং / অথবা double
<=> float
রূপান্তর। নির্দেশাবলীর মধ্যে একের চেয়েও বেশি বিলম্ব রয়েছে এবং স্কেলার ইন-> ফ্লোট ( cvtsi2ss
) খারাপভাবে তৈরি করা হয়েছে যাতে এক্স x মিমি রেজিস্টারের শূন্য নয়। (জিসিসি pxor
এই কারণে নির্ভরতা ভাঙার জন্য একটি অতিরিক্ত সন্নিবেশ করায় ।)
আপনার সিপিইউ অ্যাফিনিটিটি প্রায়শই আলাদা সিপিইউতে সেট করুন (@ ইগওয়ার দ্বারা প্রস্তাবিত)। ডায়াবলিক্যাল যুক্তি: আপনি একটি দীর্ঘ দীর্ঘ আপনার থ্রেড চালানো থেকে অত্যধিক উত্তপ্ত হতে চান না, তাই না? হতে পারে অন্য কোনও কোরে অদলবদল করার ফলে সেই কোর টার্বোকে একটি উচ্চতর ঘড়ির গতিতে দেওয়া হবে। (বাস্তবে: তারা একে অপরের সাথে তাপমাত্রার এত কাছাকাছি যে বহু-সকেট সিস্টেম ব্যতীত এটি অত্যন্ত সম্ভাবনা)। এখন কেবল টিউনিংটি ভুল করুন এবং এটি প্রায়শই ঘনিয়ে আসুন। ওএস সাশ্রয় / থ্রেডের অবস্থা পুনরুদ্ধার করতে ব্যয় করা সময় ছাড়াও, নতুন কোরটিতে শীতল এল 2 / এল 1 ক্যাশে, উওপ ক্যাশে এবং শাখার ভবিষ্যদ্বাণী রয়েছে।
ঘন ঘন অপ্রয়োজনীয় সিস্টেম কলগুলি উপস্থাপন করা সেগুলি যাই হোক না কেন আপনাকে ধীর করতে পারে। যদিও কিছু গুরুত্বপূর্ণ তবে সাধারণ বিষয়গুলি gettimeofday
ব্যবহারকারীর স্পেসে প্রয়োগ করা যেতে পারে যার সাথে কার্নেল মোডে কোনও রূপান্তর নেই। (লিনাক্সে গ্লিব্যাক কর্নেলের সাহায্যে এটি করে, যেহেতু কার্নেলটি কোডটিতে রফতানি করে vdso
)।
সিস্টেম কল ওভারহেড সম্পর্কে আরও জানতে (ব্যবহারকারী-স্পেসে ফিরে আসার পরে ক্যাশে / টিএলবি মিস করে না, কেবল প্রসঙ্গটি স্যুইচ করে না), ফ্লেক্সএসসি কাগজে বর্তমান পরিস্থিতির কিছু দুর্দান্ত পারফরম্যান্স বিশ্লেষণ রয়েছে , পাশাপাশি ব্যাচিং সিস্টেমের প্রস্তাবও রয়েছে ব্যাপকভাবে বহু-থ্রেডযুক্ত সার্ভার প্রক্রিয়াগুলি থেকে কল।
while(true){}