ইন্টেল স্যান্ডিব্রিজ-পরিবার সিপিইউগুলিতে পাইপলাইনের জন্য একটি কর্মসূচী পরিবর্তন করা


322

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

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

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

অ্যাসাইনমেন্টটি Whetstone বা মন্টে-কার্লো প্রোগ্রামগুলির একটি পছন্দ দিয়েছে। ক্যাশে-কার্যকারিতা মন্তব্যগুলি বেশিরভাগই হুইটস্টনের ক্ষেত্রে প্রযোজ্য তবে আমি মন্টে-কার্লো সিমুলেশন প্রোগ্রামটি বেছে নিয়েছি:

// Un-modified baseline for pessimization, as given in the assignment
#include <algorithm>    // Needed for the "max" function
#include <cmath>
#include <iostream>

// A simple implementation of the Box-Muller algorithm, used to generate
// gaussian random numbers - necessary for the Monte Carlo method below
// Note that C++11 actually provides std::normal_distribution<> in 
// the <random> library, which can be used instead of this function
double gaussian_box_muller() {
  double x = 0.0;
  double y = 0.0;
  double euclid_sq = 0.0;

  // Continue generating two uniform random variables
  // until the square of their "euclidean distance" 
  // is less than unity
  do {
    x = 2.0 * rand() / static_cast<double>(RAND_MAX)-1;
    y = 2.0 * rand() / static_cast<double>(RAND_MAX)-1;
    euclid_sq = x*x + y*y;
  } while (euclid_sq >= 1.0);

  return x*sqrt(-2*log(euclid_sq)/euclid_sq);
}

// Pricing a European vanilla call option with a Monte Carlo method
double monte_carlo_call_price(const int& num_sims, const double& S, const double& K, const double& r, const double& v, const double& T) {
  double S_adjust = S * exp(T*(r-0.5*v*v));
  double S_cur = 0.0;
  double payoff_sum = 0.0;

  for (int i=0; i<num_sims; i++) {
    double gauss_bm = gaussian_box_muller();
    S_cur = S_adjust * exp(sqrt(v*v*T)*gauss_bm);
    payoff_sum += std::max(S_cur - K, 0.0);
  }

  return (payoff_sum / static_cast<double>(num_sims)) * exp(-r*T);
}

// Pricing a European vanilla put option with a Monte Carlo method
double monte_carlo_put_price(const int& num_sims, const double& S, const double& K, const double& r, const double& v, const double& T) {
  double S_adjust = S * exp(T*(r-0.5*v*v));
  double S_cur = 0.0;
  double payoff_sum = 0.0;

  for (int i=0; i<num_sims; i++) {
    double gauss_bm = gaussian_box_muller();
    S_cur = S_adjust * exp(sqrt(v*v*T)*gauss_bm);
    payoff_sum += std::max(K - S_cur, 0.0);
  }

  return (payoff_sum / static_cast<double>(num_sims)) * exp(-r*T);
}

int main(int argc, char **argv) {
  // First we create the parameter list                                                                               
  int num_sims = 10000000;   // Number of simulated asset paths                                                       
  double S = 100.0;  // Option price                                                                                  
  double K = 100.0;  // Strike price                                                                                  
  double r = 0.05;   // Risk-free rate (5%)                                                                           
  double v = 0.2;    // Volatility of the underlying (20%)                                                            
  double T = 1.0;    // One year until expiry                                                                         

  // Then we calculate the call/put values via Monte Carlo                                                                          
  double call = monte_carlo_call_price(num_sims, S, K, r, v, T);
  double put = monte_carlo_put_price(num_sims, S, K, r, v, T);

  // Finally we output the parameters and prices                                                                      
  std::cout << "Number of Paths: " << num_sims << std::endl;
  std::cout << "Underlying:      " << S << std::endl;
  std::cout << "Strike:          " << K << std::endl;
  std::cout << "Risk-Free Rate:  " << r << std::endl;
  std::cout << "Volatility:      " << v << std::endl;
  std::cout << "Maturity:        " << T << std::endl;

  std::cout << "Call Price:      " << call << std::endl;
  std::cout << "Put Price:       " << put << std::endl;

  return 0;
}

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


আপডেট: এই নিয়োগটি দেওয়া প্রফেসর কিছু বিশদ পোস্ট করেছেন

হাইলাইটগুলি হ'ল:

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

মেটা থ্রেডে কাউমোগুনের মন্তব্য ইঙ্গিত দেয় যে এটি পরিষ্কার নয় যে সংকলক অপ্টিমাইজেশানগুলি এর অংশ হতে পারে, এবং ধরে নেওয়া-O0 হয়েছিল এবং রান-টাইমে 17% বৃদ্ধি যুক্তিসঙ্গত ছিল।

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


মনে রাখবেন যে এটি কম্পিউটার-আর্কিটেকচার প্রশ্ন, সাধারণভাবে সি ++ আস্তে কীভাবে করা যায় সে সম্পর্কে কোনও প্রশ্ন নয়।


97
আমি শুনেছি আই 7 খুব খারাপভাবে কাজ করেwhile(true){}
ক্লিফ এবি

3
এইচএন এটিএম-তে নম্বর 2: নিউজ.ইকোম্বিনেটর.com
item?

5
ওপেনপ্যাম সহ যদি আপনি এটি খারাপভাবে করেন তবে আপনার এন থ্রেডগুলি 1 এর চেয়ে বেশি সময় নিতে সক্ষম হওয়া উচিত
ফ্লেক্সো

9
এই প্রশ্নের এখন আলোচনা হচ্ছে মেটা
Madara এর গোস্ট

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

উত্তর:


405

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

খুব শীতল কার্যভার; আমি যেগুলি দেখেছি তার থেকে অনেক বেশি ভালো যেখানে শিক্ষার্থীদের কিছু কোডের জন্য অনুকূলকরণ করতে বলা হয়েছিল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_t32 বিবিটি সিস্টেমে প্রার্থী হওয়াটিকে একটি পারমাণবিক হার্ডওয়্যারকে আরবিট্রেট করার পরিবর্তে একটি লুপে আবার চেষ্টা করতে হবে 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 বিট ক্রিয়াকলাপ সহ আংশিক-নিবন্ধক স্টলগুলির জন্য জিসিসি পাওয়ার চেষ্টা করুন। বেশিরভাগ ক্ষেত্রে, জিসিসি movzx8 বা 16 বিটের ক্রিয়াকলাপের পরে ব্যবহার করবে , তবে এখানে একটি কেস রয়েছে যেখানে জিসিসি পরিবর্তন করে ahএবং তারপরে পাঠ করেax


(ইনলাইন) asm সহ:

(ইনলাইন) asm এর সাহায্যে আপনি ইউওপ ক্যাশেটি ভেঙে ফেলতে পারেন: একটি 32B কোডের অংশ যা তিনটি 6uop ক্যাশে লাইনে ফিট করে না the অভ্যন্তরীণ লুপের অভ্যন্তরে একটি শাখার টার্গেটে দু'জন দীর্ঘ s এর পরিবর্তে ALIGNঅনেকগুলি একক বাইট ব্যবহার করে অযোগ্য tent বা লেবেলের পরে অ্যালাইনমেন্টের প্যাডিংয়ের পরিবর্তে রাখুন instead : পি এটি কেবল তখনই বিবেচনা করে যদি সম্মুখভাগটি কোনও বাধা হয়, যা আমরা যদি বাকী কোডটি অনুমান করতে সফল হই তবে তা হবে না।nopnop

পাইপলাইন ক্লিয়ারস (ওরফে মেশিন-নিউকস) ট্রিগার করতে স্ব-পরিবর্তনকারী কোড ব্যবহার করুন।

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হতাশাবোধও করবেন (ধন্যবাদ @ জেস্পার)। এফপি তুলনা fcom686 এর চেয়ে ধীর 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)।

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


10
@ জেস্পার জুহল: হ্যাঁ, আমি এই ন্যায়সঙ্গতটি কিনব। "ডায়াবলিকভাবে অক্ষম" এমন একটি দুর্দান্ত বাক্য :)
পিটার কর্ডেস

2
ধ্রুবকের বিপরীত দ্বারা বিভাগকে ধনাত্মক দ্বারা গুণিত পরিবর্তনগুলি পরিমিতরূপে কর্মক্ষমতা হ্রাস করতে পারে (কমপক্ষে যদি কেউ -O3-ব্রেকফাস্টম্যাথকে ছাড়িয়ে যাওয়ার চেষ্টা না করে)। একইভাবে কাজ বাড়াতে সাহচর্যতা ব্যবহার করা ( exp(T*(r-0.5*v*v))হয়ে উঠছে exp(T*r - T*v*v/2.0); exp(sqrt(v*v*T)*gauss_bm)হয়ে উঠছে exp(sqrt(v)*sqrt(v)*sqrt(T)*gauss_bm)) অ্যাসোসিয়েটিভিটি (এবং exp(T*r - T*v*v/2.0)জেনারালাইজেশন) `পাও ((পাও (ই_মূল্য, টি), আর)) / পাও (পাও ((পাও (ই_মূল্য, টি), ভি), ভি)), - 2.0) [বা কিছুতে রূপান্তর করতে পারে ) এই জাতীয় গণিতের কৌশলগুলি আসলে মাইক্রোআরকিটেকচারাল ডিওপিমাইজেশন হিসাবে গণ্য হয় না
পল এ। ক্লেটন

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

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

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

35

জিনিসগুলি যতটা সম্ভব খারাপ সম্পাদন করতে আপনি কিছু কাজ করতে পারেন:

  • i386 আর্কিটেকচারের জন্য কোডটি সংকলন করুন। এটি এসএসই এবং আরও নতুন নির্দেশাবলীর ব্যবহার রোধ করবে এবং x87 এফপিইউ ব্যবহারকে বাধ্য করবে।

  • std::atomicসর্বত্র চলক ব্যবহার করুন । সংকলকটি পুরো জায়গা জুড়ে মেমরির বাধা toোকাতে বাধ্য করার কারণে এটি তাদের খুব ব্যয়বহুল করে তুলবে। এবং এটি একটি অক্ষম ব্যক্তি "থ্রেড সুরক্ষা নিশ্চিত করতে" প্রশংসনীয়ভাবে করতে পারে।

  • প্রিফেটচারের পূর্বাভাস দেওয়ার জন্য খারাপতম উপায়ে মেমরি অ্যাক্সেস করার বিষয়টি নিশ্চিত করুন (কলাম মেজ বনাম সারি মেজর)।

  • আপনার ভেরিয়েবলগুলি অতিরিক্ত ব্যয়বহুল করার জন্য আপনি নিশ্চিত করতে পারেন যে তাদের সকলকে new'স্বয়ংক্রিয় স্টোরেজ সময়কাল' (স্ট্যাক বরাদ্দ) না দিয়ে বরাদ্দ দিয়ে তাদের 'গতিশীল স্টোরেজ সময়কাল' (গাদা বরাদ্দ) রয়েছে।

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

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

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


9
এর মধ্যে কয়েকটি সম্পর্কে আমার প্রধান আপত্তি হ'ল প্রশ্নের বাক্যবিন্যাস : প্রোগ্রামটি ডিউটিমাইজ করতে আপনার কীভাবে ইন্টেল আই 7 পাইপলাইনটি পরিচালনা করে তা আপনার জ্ঞানটি ব্যবহার করুন আমার মনে হয় না যে এক্স ৮ about, বা std::atomicগতিশীল বরাদ্দ থেকে অতিরিক্ত স্তরের ইন্ডিয়ারেশনের বিষয়ে নির্দিষ্ট কিছু আছে । তারা এটম বা কে 8 তেও ধীর হতে চলেছে। তবুও উত্সাহ দেওয়া হচ্ছে, তবে সে কারণেই আমি আপনার কয়েকটি পরামর্শ প্রতিহত করছি।
পিটার কর্ডেস

এগুলি ন্যায্য পয়েন্ট। নির্বিশেষে, সেই জিনিসগুলি এখনও কিছুটা জিজ্ঞাসকের লক্ষ্যের দিকে কাজ করে। উত্স প্রশংসা :)
জেস্পার জুহল

এসএসই ইউনিট 0, 1 এবং 5 বন্দর ব্যবহার করে x87 ইউনিট কেবল 0 এবং 1 পোর্ট ব্যবহার করে
মাইচাস

@ মিছাস: আপনি সে সম্পর্কে ভুল। হাসওয়েল বন্দর ৫ এ কোনও এসএসই এফপি গণিতের নির্দেশনা চালায় না Most বেশিরভাগ এসএসই এফপি শফলস এবং বুলিয়ানস (xorps / andps / orps)। x87 ধীর, তবে কেন সামান্য ভুল তা আপনার ব্যাখ্যা। (এবং এই বিষয়টি সম্পূর্ণ ভুল))
পিটার কর্ডেস

1
@ মিছাস: movapd xmm, xmmসাধারণত একটি এক্সিকিউশন পোর্টের প্রয়োজন হয় না (এটি আইভিবিতে রেজিস্টার-নামকরণ পর্যায়ে এবং পরবর্তী সময়ে পরিচালিত হয়)। এটি এভিএক্স কোডে প্রায় প্রয়োজন হয় না, কারণ এফএমএ ছাড়া সমস্ত কিছুই অ-ধ্বংসাত্মক। তবে যথেষ্ট ন্যায্য, হাসওয়েল এটি পোর্ট 5 এ চালায় যদি এটি অপসারণ না হয়। আমি x87 রেজিস্টার-অনুলিপি ( fld st(i)) এর দিকে নজর দিইনি তবে আপনি হ্যাসওয়েল / ব্রডওয়েলের পক্ষে ঠিক বলেছেন: এটি p01 এ চলে। স্কাইলেক এটিকে পি05 এ চালায়, এসএনবি এটি পি 0 এ চালায়, আইভিবি এটি পি 5 এ চালায়। সুতরাং আইভিবি / এসকেএল পি 5-তে কিছু x87 স্টাফ (তুলনা সহ) করে তবে এসএনবি / এইচএসডাব্লু / বিডিডাব্লু x87 এর জন্য পি 5 ব্যবহার করে না।
পিটার কর্ডেস

11

আপনি long doubleগণনার জন্য ব্যবহার করতে পারেন । X86 এ এটি 80-বিট ফর্ম্যাট হওয়া উচিত। শুধুমাত্র উত্তরাধিকার, x87 এফপিইউ এর পক্ষে সমর্থন করে।

X87 এফপিইউর কয়েকটি ত্রুটি:

  1. সিমডের অভাব, আরও নির্দেশের প্রয়োজন হতে পারে।
  2. স্ট্যাক ভিত্তিক, সুপার স্কেলার এবং পাইপলাইনযুক্ত স্থাপত্যগুলির জন্য সমস্যাযুক্ত।
  3. পৃথক এবং বেশ কয়েকটি ছোট সেট রেজিস্টারগুলিতে অন্যান্য রেজিস্টারগুলির থেকে আরও রূপান্তর এবং আরও মেমরি অপারেশনগুলির প্রয়োজন হতে পারে।
  4. কোর আই 7 এ এসএসইর জন্য 3 টি এবং এক্স 8 এর জন্য কেবল 2 টি বন্দর রয়েছে, প্রসেসর কম সমান্তরাল নির্দেশাবলী সম্পাদন করতে পারে।

3
স্কেলার গণিতের জন্য, x87 গণির নির্দেশাবলী সেগুলি কেবল সামান্য ধীর। 10byte অপারেন্ডস সংরক্ষণ / লোড করা উল্লেখযোগ্যভাবে ধীর, যদিও এবং x87 এর স্ট্যাক-ভিত্তিক ডিজাইনের অতিরিক্ত নির্দেশাবলীর প্রয়োজন (যেমন fxch)। এর সাথে -ffast-math, একটি ভাল সংকলক মন্টে-কার্লো লুপগুলি ভেক্টরাইজ করতে পারে, এবং x87 এটি প্রতিরোধ করবে।
পিটার কর্ডেস

আমি আমার উত্তরটি কিছুটা বাড়িয়ে দিয়েছি।
মিশাস

1
পুনরায়: 4: আপনি কোন আই 7 এরচ সম্পর্কে কথা বলছেন এবং কোন নির্দেশাবলী? হাসওয়েল mulssp01 এ চলতে পারে তবে fmulকেবল চালু p0addssশুধুমাত্র চলমান p1, হিসাবে একই fadd। কেবলমাত্র দুটি এক্সিকিউশন পোর্ট রয়েছে যা এফপি গণিতের অপশন পরিচালনা করে। (এই একমাত্র ব্যতিক্রম যে Skylake ডেডিকেটেড অ্যাড ইউনিট এবং রান অবনমিত হয়েছে addssP01 উপর FMA এককে কিন্তু faddp5 উপর তাই কিছু মধ্যে মিশিয়ে। faddবরাবর নির্দেশাবলী fma...ps, আপনি তত্ত্ব সামান্য বেশি মোট ফ্লপ করতে পারি না / s।)
পিটার কর্ডেস

2
এছাড়াও নোট করুন যে উইন্ডোজ x86-64 এবিআইয়ের 64 বিট রয়েছে long double, এটি এখনও ঠিক doublelong doubleযদিও এসআইএসভি এবিআই 80 বিট ব্যবহার করে । এছাড়াও, পুনরায়: 2: রেজিস্টার নামকরণ স্ট্যাকের নিবন্ধগুলিতে সমান্তরালতা প্রকাশ করে। স্ট্যাক-ভিত্তিক আর্কিটেকচারের জন্য কিছু অতিরিক্ত নির্দেশাবলীর প্রয়োজন, যেমন fxchg, এসএসপি। যখন আন্তঃলিখন সমান্তরাল গণনা। সুতরাং এর চেয়ে বেশি যেমন মেমরির রাউন্ড-ট্রিপগুলি না করে সমান্তরালতা প্রকাশ করা শক্ত, বরং এর থেকে যা আছে তা কাজে লাগানো তার পক্ষে শক্ত than যদিও আপনাকে অন্য রেজি থেকে আরও রূপান্তরের দরকার নেই। আপনি যে দ্বারা অর্থ কি নিশ্চিত নয়।
পিটার কর্ডেস

6

দেরিতে উত্তর কিন্তু আমি মনে করি না যে আমরা লিঙ্কযুক্ত তালিকাগুলি এবং টিএলবি যথেষ্ট পরিমাণে আপত্তি করেছি।

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

একক সংযুক্ত তালিকা থেকে পড়ার সময়, একক সংখ্যা পড়তে সর্বাধিক বিলম্বের কারণ হিসাবে প্রতিবারের তালিকাটি শুরু থেকে পড়তে ভুলবেন না।


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

তবে হ্যাঁ, মজার ধারণা। আপনি হয়তো ব্যবহার করতে পারে mmapএকটি ফাইল বা শেয়ার করা মেমরি অঞ্চলের উপর, একই শারীরিক পৃষ্ঠা (একই বিষয়বস্তু সঙ্গে) জন্য একাধিক ভার্চুয়াল অ্যাড্রেস পেতে প্রকৃত RAM একই পরিমাণ উপর আরো বেশি TLB শটটি অনুমতি দেয়। যদি আপনার লিঙ্কযুক্ত- তালিকাগুলিnext কেবল একটি আপেক্ষিক অফসেট হয় , +4096 * 1024আপনি অবশেষে অন্য কোনও শারীরিক পৃষ্ঠায় না পৌঁছানো পর্যন্ত একই পৃষ্ঠার ম্যাপিংগুলির একটি সিরিজ থাকতে পারে । অথবা অবশ্যই L1d ক্যাশে হিটগুলি এড়াতে একাধিক পৃষ্ঠাগুলিতে বিস্তৃত। পৃষ্ঠা-ওয়াক হার্ডওয়ারের মধ্যে উচ্চ-স্তরের পিডিইগুলির ক্যাচিং রয়েছে, তাই হ্যাঁ এটি এটিকে অ্যাড্রেস স্পেসে ছড়িয়ে দিন!
পিটার কর্ডস

পুরানো ঠিকানায় একটি অফসেট যুক্ত করাও [ [reg+small_offset]অ্যাড্রেসিং মোডের জন্য বিশেষ ক্ষেত্রে ] পরাজিত করে লোড-ব্যবহারের বিলম্বকে আরও খারাপ করে তোলে ( বেস + অফসেট বেসের চেয়ে আলাদা পৃষ্ঠায় থাকলে কোনও জরিমানা রয়েছে কি? ); আপনি হয় addএকটি 64-বিট অফসেটের একটি মেমরি উত্স পেতে চাইবেন বা আপনি একটি লোড এবং একটি সূচিযুক্ত ঠিকানা মোডের মতো পেতে পারেন [reg+reg]। এছাড়াও দেখুন একটি এল 2 টিএলবি মিস করার পরে কী ঘটে? - পৃষ্ঠা ওয়াকটি এসএনবি-পরিবারে এল 1 ডি ক্যাশে প্রবেশ করে।
পিটার কর্ডস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.