পারফরম্যান্স উন্নত করতে সিপিইউ ক্যাশে সর্বোত্তমভাবে ব্যবহার করে এমন একটি লিখন কোড কীভাবে ব্যবহার করবে?


159

এটি একটি বিষয়গত প্রশ্নের মতো শোনাতে পারে তবে আমি যা খুঁজছি তা সুনির্দিষ্ট উদাহরণ, যা আপনি এর সাথে সম্পর্কিত হতে পারেন।

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

  2. কোড ক্যাশে কার্যকর করার জন্য এমন কি কোনও নির্দিষ্ট ডেটা স্ট্রাকচার অবশ্যই ব্যবহার / এড়াতে হবে, বা সেই কাঠামোর সদস্যদের অ্যাক্সেস করার কোনও বিশেষ উপায় আছে ...?

  3. এই ক্ষেত্রে কোনও প্রোগ্রাম (যদি, স্যুইচ, ব্রেক, গোটো, ...), কোড-ফ্লো (যদি একটি আইফোনের ভিতরে, যদি একটি জন্য, ইত্যাদি ...) থাকে তবে কি এই বিষয়টিকে অনুসরণ করা / এড়ানো উচিত?

আমি সাধারণভাবে ক্যাশে দক্ষ কোড তৈরির সাথে সম্পর্কিত পৃথক অভিজ্ঞতা শোনার জন্য অপেক্ষা করছি। এটি যে কোনও প্রোগ্রামিং ল্যাঙ্গুয়েজ (সি, সি ++, এসেম্বলি, ...), কোনও হার্ডওয়্যার টার্গেট (এআরএম, ইন্টেল, পাওয়ারপিসি, ...), যে কোনও ওএস (উইন্ডোজ, লিনাক্স, এস ইম্বিয়ান, ...) ইত্যাদি হতে পারে etc. ।

বিভিন্নটি গভীরভাবে এটি বুঝতে আরও সহায়তা করবে।


1
ভূমিকা হিসাবে এই
আলোচনাটি

উপরের সংক্ষিপ্ত URL টি আর কাজ করছে বলে মনে হয় না, এটি আলাপের পুরো URL: youtube.com/watch?v=BP6NxVxDQIs
অভিনব উপাধ্যায়

উত্তর:


119

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

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

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

ক্যাশে লাইন ব্যবহারের উন্নতি তিন ক্ষেত্রে সহায়তা করে:

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

সাধারণ কৌশলগুলি হ'ল:

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

আমাদের এটিও লক্ষ্য করা উচিত যে ক্যাশে ব্যবহারের চেয়ে স্মৃতিতে বিলম্বিতা আড়াল করার অন্যান্য উপায় রয়েছে।

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

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

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

একই ডেটা ( লুপ ফিউশন ) স্পর্শকারী লুপগুলি মার্জ করে এবং পুনরায় লেখার কৌশলগুলি নিয়োগ করে যা টাইলিং বা সমস্তকে অবরুদ্ধ করে বলে extra অতিরিক্ত মেমরি সংগ্রহগুলি এড়াতে চেষ্টা করে।

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

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


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

"প্রান্তিককরণের ছিদ্রগুলি এড়াতে আপনার ডেটা সংগঠিত করুন (আকার কমিয়ে আপনার কাঠামোর সদস্যদের বাছাই করা এক উপায়)" - সংকলক কেন এটিকে নিজেরাই অনুকূলিত করে না? সংকলক সর্বদা "আকার হ্রাস করে সদস্যদের বাছাই করতে" পারে না কেন? সদস্যদের অরক্ষিত রাখার সুবিধা কী?
javapowered

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

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

56

আমি বিশ্বাস করতে পারি না এর আরও উত্তর নেই। যাইহোক, একটি ক্লাসিক উদাহরণ একটি বহুমাত্রিক অ্যারে "ভিতরে বাইরে" পুনরাবৃত্তি করা:

pseudocode
for (i = 0 to size)
  for (j = 0 to size)
    do something with ary[j][i]

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

for (i = 0 to size)
  for (j = 0 to size)
    do something with ary[i][j]

এটি অনেক দ্রুত চলবে।


9
কলেজে ফিরে আমাদের ম্যাট্রিক্সের গুণায় একটি অ্যাসাইনমেন্ট ছিল। দেখা গেল যে "কলামগুলি" ম্যাট্রিক্সের ট্রান্সপোজ নেওয়া এবং সুনির্দিষ্ট কারণে কলসের সাহায্যে সারিগুলির চেয়ে সারিগুলিতে সারিগুলি গুণ করা দ্রুত ছিল।
ykaganovich

11
প্রকৃতপক্ষে, আধুনিক সংকলকগুলির বেশিরভাগই এটি নিজেই আবিষ্কার করতে পারেন (অনুকূলিতকরণ চালু করে)
রিকার্ডো নলদে

1
@ ইয়াকাগানোভিচ এটিও আলরিক ড্রেপার্স নিবন্ধে উদাহরণ: lwn.net/Articles/255364
সাইমন স্টেন্ডার

আমি নিশ্চিত না যে এটি সর্বদা সঠিক - যদি পুরো অ্যারেটি L1 ক্যাশে (প্রায়শই 32 কে!) এর মধ্যে ফিট করে তবে উভয় আদেশেই একই সংখ্যায় ক্যাশে হিট এবং মিস হবে। সম্ভবত মেমরির প্রাক-আনতে আমার ধারণা কিছুটা প্রভাব ফেলতে পারে। অবশ্যই সংশোধন হতে পেরে আনন্দিত।
ম্যাট পার্কিন্স 4:58

যদি আদেশের বিষয়টি বিবেচনা না করে তবে এই কোডের প্রথম সংস্করণটি কে কখন বেছে নেবে?
রৌপ্য_রোকেট

45

প্রাথমিক নিয়মগুলি মোটামুটি সহজ। এটি কোথায় জটিল হয় তা আপনার কোডটিতে কীভাবে প্রয়োগ হয় your

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

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

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

একটি সাধারণ উদাহরণ 200 অ্যারে ট্র্যাভারসাল যা 1800 এর উত্তর দেখিয়েছে। যদি আপনি এটি একবারে এক সারি অতিক্রম করেন, আপনি ক্রমান্বয়ে স্মৃতিটি পড়ছেন। আপনি যদি এটি কলাম অনুসারে করেন তবে আপনি একটি এন্ট্রি পড়বেন, তারপরে একেবারে পৃথক স্থানে (পরের সারিটির শুরুতে) ঝাঁপিয়ে পড়ুন, একটি প্রবেশিকা পড়ুন এবং আবার লাফ দিন। এবং অবশেষে আপনি যখন প্রথম সারিতে ফিরে আসবেন, তখন এটি আর ক্যাশে থাকবে না।

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

নির্দেশের ক্যাশে ব্যবহার সাধারণত কোনও সমস্যার তুলনায় অনেক কম। আপনার সাধারণত যা উদ্বিগ্ন হওয়া দরকার তা হ'ল ডেটা ক্যাশে।

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

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


4
+1, ভাল এবং ব্যবহারিক পরামর্শ। একটি সংযোজন: সময়ের লোকাল এবং স্পেস লোকাল সম্মিলিত পরামর্শ দেয় যে ম্যাট্রিক্স অপের জন্য উদাহরণস্বরূপ, এগুলি ছোট ম্যাট্রিকগুলিতে বিভক্ত করার পরামর্শ দেওয়া হতে পারে যা সম্পূর্ণরূপে ক্যাশে লাইনে ফিট থাকে বা যার সারি / কলামগুলি ক্যাশে লাইনে ফিট করে। আমার মনে আছে মাল্টিমিডিমের ভিজ্যুয়ালাইজেশনের জন্য এটি করা। ডেটা। এটি প্যান্টগুলিতে কিছু মারাত্মক কিক সরবরাহ করেছিল। এটি মনে রাখা ভাল যে ক্যাশে একাধিক 'লাইন' ধারণ করে;)
AndreasT

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

2
@ জোসেফগারভিন: হ্যাঁ, আমি লিখতে চাইছিলাম। আপনি ঠিক বলেছেন, একাধিক কোরের একই সময়ে তাদের L1 ক্যাশে একই ক্যাশে রেখাগুলি থাকতে পারে, তবে যখন একটি কোর এই ঠিকানাগুলিতে লিখবে, তখন এটি অন্যান্য সমস্ত এল 1 ক্যাশে অবৈধ হয়ে যায় এবং তারপরে তারা তাদের পুনরায় লোড করতে হয় do এটি দিয়ে কিছু। ভুল শব্দটির জন্য দুঃখিত। :)
জলফ

44

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

এই প্রশ্নের সাথে বিশেষত প্রাসঙ্গিক বিভাগগুলি পার্ট 2 (সিপিইউ ক্যাশে) এবং পর্ব 5 (প্রোগ্রামাররা কি করতে পারে - ক্যাশে অপ্টিমাইজেশন) হতে পারে।


16
নিবন্ধ থেকে আপনার প্রধান পয়েন্টগুলির সংক্ষিপ্তসার যুক্ত করা উচিত।
আজমিসভ

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

15

ডেটা অ্যাক্সেসের নিদর্শনগুলি ছাড়াও ক্যাশে-বান্ধব কোডের একটি প্রধান কারণটি হ'ল ডেটা আকার । কম ডেটা মানে এর বেশিরভাগটি ক্যাশে ফিট করে।

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

একইভাবে, একটি জাভা বুলিয়ান অ্যারে প্রত্যেকে পৃথক মানগুলিতে সরাসরি অপারেশন করার জন্য প্রতিটি মানের জন্য একটি সম্পূর্ণ বাইট ব্যবহার করে। আপনি 8 টির একটি ফ্যাক্টর দ্বারা ডেটা আকার হ্রাস করতে পারবেন যদি আপনি প্রকৃত বিট ব্যবহার করেন তবে পৃথক মানগুলিতে অ্যাক্সেস অনেক জটিল হয়ে যায়, বিট শিফট এবং মাস্ক ক্রিয়াকলাপের প্রয়োজন হয় ( BitSetশ্রেণিটি এটি আপনার জন্য করে)। যাইহোক, ক্যাশে প্রভাবের কারণে, অ্যারে বড় হয়ে যাওয়ার পরে এটি বুলিয়ান [] ব্যবহারের চেয়ে যথেষ্ট দ্রুত হতে পারে। আইআইআরসি আমি একবার 2 বা 3 এর ফ্যাক্টর দ্বারা এইভাবে একটি স্পিডআপ অর্জন করেছি।


9

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

যেকোনও অ্যালগরিদম যা এলোমেলো ক্রমে স্মৃতিতে অ্যাক্সেস করে তা ক্যাশে ট্র্যাশ করে কারণ এলোমেলোভাবে অ্যাক্সেস করা মেমরিটি সামঞ্জস্য রাখতে এটি সর্বদা নতুন ক্যাশে লাইন প্রয়োজন। অন্যদিকে একটি অ্যালগরিদম, যা ক্রমান্বয়ে অ্যারের মাধ্যমে সঞ্চালিত হয় তা সেরা কারণ:

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

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


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

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

আরও একটি দ্রষ্টব্য: আপনি যদি লুপটি থেকে কল করেন এবং পর্যাপ্ত ক্যাশে স্থান না পান তবে নির্বিশেষে নতুন ফাংশনটি ক্যাশে লোড করা হবে। এমনকি এটিও ঘটতে পারে যে আসল লুপটি ক্যাশে থেকে ফেলে দেওয়া হবে। এক্ষেত্রে কলটির প্রতিটি পুনরাবৃত্তির জন্য তিনটি জরিমানা লাগতে পারে: একটি কল টার্গেট লোড করতে এবং অন্যটি লুপটি পুনরায় লোড করতে। এবং তৃতীয়টি যদি লুপ হেড কল রিটার্ন ঠিকানার ঠিক একই ক্যাশে লাইনে না থাকে। সেক্ষেত্রে লুপ মাথায় লাফিয়ে উঠার জন্য একটি নতুন মেমরি অ্যাক্সেস প্রয়োজন।
গ্রোভার 13

8

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

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

বিভিন্ন উপায়ে এটি অবজেক্ট-ওরিয়েন্টেড ডিজাইনের নিদর্শন লঙ্ঘন করেছে তবে একই লুপগুলিতে অপারেশন করা দরকার এমন ডেটা একসাথে রেখে এটি কোডটি আরও দ্রুত তৈরি করেছিল।

এই উদাহরণটি সম্ভবত পুরানো because কারণ আমি আশা করি বেশিরভাগ আধুনিক গেমগুলি হাভোকের মতো প্রাক-বিল্ট ফিজিক্স ইঞ্জিন ব্যবহার করে।


2
+1 পুরানো কিছু নয়। এটি গেম ইঞ্জিনগুলির জন্য ডেটা সংগঠিত করার সেরা উপায় - ক্যাশের সান্নিধ্য / স্থানীয়তা লাভের জন্য পরের দিকে (পদার্থবিজ্ঞান বলুন) এগিয়ে যাওয়ার পূর্বে ডেটা ব্লকগুলিকে সামঞ্জস্যপূর্ণ করা এবং প্রদত্ত সমস্ত ধরণের অপারেশন (এআই বলুন) সম্পাদন করুন perform রেফারেন্স।
ইঞ্জিনিয়ার

আমি সপ্তাহে কয়েক সপ্তাহ আগে কোথাও একটি ভিডিওতে এই সঠিক উদাহরণটি দেখেছি, তবে তার থেকে এর লিঙ্কটি হারিয়ে গেছে / কীভাবে এটি সন্ধান করতে হবে তা মনে করতে পারছি না। আপনি যেখানে এই উদাহরণটি দেখেছেন মনে আছে?
হবে

@ উইল: না, ঠিক কোথায় ছিল তা আমার মনে নেই।
ঝ্যান লিংস

এটি একটি সত্তা উপাদান সিস্টেমের খুব ধারণা (ইসিএস: en.wikedia.org/wiki/Entity_comp جز_ সিস্টেম )। ওওপি অনুশীলনগুলি উত্সাহিত করে এমন আরও traditionalতিহ্যবাহী অ্যারে অফ স্ট্রাক্টের চেয়ে ডেটা স্ট্রাক্ট অফ অফ অ্যারে হিসাবে সঞ্চয় করুন Store
বুশনিকনিক

7

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


7

1800 ব্যবহারকারীর তথ্য দ্বারা "ক্লাসিক উদাহরণ" - এ মন্তব্য (কোনও মন্তব্যের জন্য খুব দীর্ঘ)

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

measure::start();
for ( int y = 0; y < N; ++y )
for ( int x = 0; x < N; ++x )
    sum += A[ x + y*N ];
measure::stop();

এবং forলুপগুলির সাথে দ্বিতীয় কেসটি অদলবদল করে।

ধীর সংস্করণ ("x প্রথম") ছিল 0.88 সেকস এবং দ্রুততমটি ছিল 0.06 সেকেন্ড। এটাই ক্যাচিংয়ের শক্তি :)

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


আমি নিশ্চিত যে নিশ্চিত। উভয় উদাহরণে আপনি এখনও লুপের জন্য প্রতিটি ভেরিয়েবল অ্যাক্সেস করছেন। এক রাস্তা অন্য পথের চেয়ে দ্রুত কেন?
এড-

এটি কীভাবে প্রভাবিত করে তা বুঝতে আমার কাছে শেষ পর্যন্ত স্বজ্ঞাত :)
Laie

@ এডওয়ার্ডকর্লিউ এটি তাদের ক্রম যে ক্রমটি অ্যাক্সেস করেছে সে কারণে এটি। ওয়াই-ফার্স্ট অর্ডারটি দ্রুততর কারণ এটি ক্রমে ডেটা অ্যাক্সেস করে। প্রথম প্রবেশের জন্য যখন অনুরোধ করা হয় এল 1 ক্যাশে একটি সম্পূর্ণ ক্যাশে-লাইন লোড করে, যার মধ্যে অন্তর্ভুক্ত অনুরোধ করা প্লাস পরবর্তী 15 (একটি 64-বাইট ক্যাশে-লাইন ধরে) অন্তর্ভুক্ত থাকে, সুতরাং পরবর্তী 15 এর জন্য অপেক্ষা করা কোনও সিপিইউ স্টল নেই The x প্রথম অর্ডারটি ধীরে ধীরে কারণ অ্যাক্সেস করা উপাদানটি অনুক্রমিক নয়, এবং সম্ভবত এন যথেষ্ট পরিমাণে বড় যে মেমরিটি অ্যাক্সেস করা হচ্ছে সর্বদা L1 ক্যাশের বাইরে থাকে এবং তাই প্রতিটি ক্রিয়াকলাপ স্টলের।
ম্যাট পার্কিন্স 4'16

4

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


@ অ্যান্ড্রু: স্ট্রাকচার সম্পর্কে কীভাবে। তারা কি ক্যাশে দক্ষ? ক্যাশে দক্ষ হওয়ার জন্য তাদের কি আকারের কোনও বাধা আছে?
গোল্ডেনম্যান

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

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

অবশ্যই, তবে এটি অনেক কাজ std :: list <> এট আল পেয়ে চলেছে। আপনার কাস্টম মেমরি ব্লক ব্যবহার করতে। যখন আমি অল্প বয়স্ক হুইপার্সনার ছিলাম আমি একেবারে সেই পথেই যেতে পারতাম, কিন্তু এই দিনগুলিতে ... সামলাতে আরও অনেক কিছুই things
অ্যান্ড্রু


4

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

একক ক্যাশে-লাইনের মধ্যে থাকা ডেটা স্ট্রাকচারগুলি তাই আরও দক্ষ।

একইভাবে, অ্যালগরিদমগুলি যা অবিচ্ছিন্ন মেমরি ব্লকগুলিতে অ্যাক্সেস করে তা অ্যালগরিদমের চেয়ে বেশি কার্যকর হবে যা এলোমেলো ক্রমে মেমরির মধ্য দিয়ে যায়।

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


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

4

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

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

(বিটিডব্লিউ - ক্যাশে-মিসের মতো খারাপ হতে পারে, আরও খারাপ হতে পারে - যদি কোনও প্রোগ্রাম হার্ড-ড্রাইভ থেকে পেজিং করে ...)


4

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

ধারণাটি অন্যান্য পাইপলাইনিং কৌশলগুলি থেকে নেওয়া, যেমন সিপিইউ নির্দেশিকা পাইপলাইনিং।

এই ধরণের প্যাটার্নগুলি সর্বোত্তম পদ্ধতিগুলির ক্ষেত্রে প্রযোজ্য

  1. যুক্তিসঙ্গত একাধিক সাব-স্টেপ, এস [1], এস [2], এস [3], ... যাঁর মৃত্যুর সময়টি প্রায় র‌্যাম অ্যাক্সেস সময় (time 60-70ns) এর সাথে তুলনীয় to
  2. ফলাফল পেতে তাদের উপর একটি ব্যাচ ইনপুট নেয় এবং উপরে উল্লিখিত একাধিক পদক্ষেপ গ্রহণ করে।

আসুন একটি সাধারণ কেস নেওয়া যাক যেখানে কেবলমাত্র একটি উপ-পদ্ধতি রয়েছে। সাধারণত কোডটি পছন্দ করে:

def proc(input):
    return sub-step(input))

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

def batch_proc(inputs):
    results = []
    for i in inputs:
        // avoids code cache miss, but still suffer data(inputs) miss
        results.append(sub-step(i))
    return res

তবে, যেমন আগেই বলা হয়েছে, পদক্ষেপের বাস্তবায়ন যদি র‌্যাম অ্যাক্সেসের সময়ের মতোই হয় তবে আপনি কোডটিকে আরও ভালো কিছুতে উন্নত করতে পারেন:

def batch_pipelined_proc(inputs):
    for i in range(0, len(inputs)-1):
        prefetch(inputs[i+1])
        # work on current item while [i+1] is flying back from RAM
        results.append(sub-step(inputs[i-1]))

    results.append(sub-step(inputs[-1]))

মৃত্যুদন্ড কার্যকর প্রবাহ দেখতে হবে:

  1. প্রিফেচ (১) সিপিইউকে ক্যাশে প্রিফেট করতে [1] জিজ্ঞাসা করুন, যেখানে প্রিফেচ নির্দেশিকা নিজেই পি চক্র গ্রহণ করে এবং ফিরে আসে, এবং ব্যাকগ্রাউন্ড ইনপুট [1] আর চক্রের পরে ক্যাশে পৌঁছায়।
  2. work_on (0) শীতল মিস 0 এবং এটিতে কাজ করে, যা এম নেয়
  3. প্রিফেট (2) আরেকটি আনতে ইস্যু করে
  4. work_on (1) যদি P + R <= M হয়, তবে ইনপুটস [1] এই পদক্ষেপের আগেই ক্যাশে থাকা উচিত, সুতরাং ডেটা ক্যাশে মিস এড়ানো উচিত
  5. work_on (2) ...

আরও পদক্ষেপ জড়িত থাকতে পারে, তারপরে আপনি একটি মাল্টি-স্টেজ পাইপলাইন ডিজাইন করতে পারবেন যতক্ষণ না ধাপের সময় এবং মেমরির অ্যাক্সেস ল্যাটেন্সির মিলগুলি মিলবে আপনি সামান্য কোড / ডেটা ক্যাশে মিস করবেন। যাইহোক, পদক্ষেপ এবং প্রিফেচ সময় সঠিক গ্রুপিংয়ের জন্য এই প্রক্রিয়াটি অনেক পরীক্ষার সাথে সুর করা প্রয়োজন tun এর প্রয়োজনীয় প্রচেষ্টার কারণে এটি উচ্চ কার্যকারিতা ডেটা / প্যাকেট স্ট্রিম প্রসেসিংয়ে আরও গ্রহণ গ্রহণ করে। DPDK QoS এনকুই পাইপলাইন নকশায় একটি ভাল উত্পাদন কোড উদাহরণ পাওয়া যায়: http://dpdk.org/doc/guides/prog_guide/qos_framework.html অধ্যায় 21.2.4.3। পাইপলাইন এঁকে দিন।

আরও তথ্য পাওয়া যাবে:

https://software.intel.com/en-us/articles/memory-management-for-optimal-performance-on-intel-xeon-phi-coprocessor-alignment-and

http://infolab.stanford.edu/~ullman/dragon/w06/lectures/cs243-lec13-wei.pdf


1

একটি ন্যূনতম আকার নিতে আপনার প্রোগ্রাম লিখুন। এজন্য জিসিসির জন্য -O3 অপটিমাইজেশন ব্যবহার করা সর্বদা ভাল ধারণা নয়। এটি আরও বড় আকার নেয় takes প্রায়শই, -Os -O2 এর মতোই ভাল। এটি সমস্ত যদিও ব্যবহৃত প্রসেসরের উপর নির্ভর করে। YMMV।

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

আপনাকে নির্দেশের অস্থায়ী / স্থানিক স্থানের আরও ভাল ব্যবহার করতে সহায়তা করার জন্য, আপনি কীভাবে আপনার কোডটি অ্যাসেমব্লিতে রূপান্তরিত করতে পারেন তা অধ্যয়ন করতে চাইতে পারেন। উদাহরণ স্বরূপ:

for(i = 0; i < MAX; ++i)
for(i = MAX; i > 0; --i)

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


আকর্ষণীয় বিষয়। লুক-ফরোয়ার্ড ক্যাচগুলি কী কোনও লুপ / ​​স্মৃতির মধ্য দিয়ে যাওয়ার দিকের ভিত্তিতে অনুমানগুলি তৈরি করে?
অ্যান্ড্রু

1
অনুমানমূলক ডেটা ক্যাশে ডিজাইনের অনেকগুলি উপায় রয়েছে। স্ট্রাইড ভিত্তিকগুলি ডেটা অ্যাক্সেসগুলির 'দূরত্ব' এবং 'দিকনির্দেশ' পরিমাপ করে। বিষয়বস্তু ভিত্তিকগুলি পয়েন্টার চেইনগুলি তাড়া করে। সেগুলি ডিজাইনের অন্যান্য উপায়ও রয়েছে।
syberon

1

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

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