আমি " সীমাবদ্ধতার " শর্তে পারফরম্যান্সের কথা ভাবতে চাই । এটি একটি মোটামুটি জটিল, আন্তঃসংযুক্ত সিস্টেমকে ধারণা দেওয়ার এক সহজ উপায়। আপনার কোনও পারফরম্যান্স সমস্যা হলে আপনি প্রশ্নটি জিজ্ঞাসা করেন: "আমি কোন সীমাবদ্ধতা দিচ্ছি?" (বা: "আমি কি সিপিইউ / জিপিইউ আবদ্ধ?")
আপনি এটিকে একাধিক স্তরে বিভক্ত করতে পারেন। সর্বোচ্চ স্তরে আপনার সিপিইউ এবং জিপিইউ রয়েছে। আপনি সিপিইউ বাউন্ড (সিপিইউর অপেক্ষায় জিপিইউ বসে আছেন), বা জিপিইউ বাউন্ড (সিপিইউ জিপিইউতে অপেক্ষা করছেন) হতে পারেন। এখানে বিষয় সম্পর্কে একটি ভাল ব্লগ পোস্ট ।
আপনি এটিকে আরও ভেঙে ফেলতে পারেন। উপর CPU- র পাশ, আপনি CPU- র ক্যাশের মধ্যে ডেটা ইতিমধ্যে আপনার সব চক্র ব্যবহার হতে পারে। অথবা আপনি মেমরি সীমাবদ্ধ হতে পারেন , সিপিইউ নিষ্ক্রিয় রেখে মূল স্মৃতি থেকে ডেটা আসার অপেক্ষায় থাকে ( সুতরাং আপনার ডেটা বিন্যাসটি অনুকূলিত করুন )। আপনি এটিকে আরও ভেঙে ফেলতে পারেন।
(আমি এক্সএনএ সম্পর্কিত পারফরম্যান্সের একটি বিস্তৃত পর্যালোচনা করার সময়, আমি উল্লেখ করব যে একটি রেফারেন্স ধরণের বরাদ্দ ( class
না struct
), সাধারণত সস্তা সস্তা, আবর্জনা সংগ্রহকারীকে ট্রিগার করতে পারে, যা প্রচুর চক্র জ্বালিয়ে দেবে - বিশেষত এক্সবক্স ৩ 360০ এ । এখানে দেখুন বিস্তারিত জানার জন্য)।
উপর জিপিইউ পাশ, আমি আপনার প্রতি নির্দেশ করে আউট শুরু করব এই চমৎকার ব্লগ পোস্টে যা বিবরণ প্রচুর হয়েছে। আপনি যদি পাইপলাইনে একটি উন্মাদ স্তরের বিশদ চান , তবে এই সিরিজের ব্লগ পোস্টগুলি পড়ুন । ( এখানে একটি সহজ সরল )।
এটিকে এখানে সহজভাবে বলতে গেলে, কয়েকটি বড় হ'ল : " ফিল লিমিট " (ব্যাকবফারটিতে আপনি কত পিক্সেল লিখতে পারেন - প্রায়শই আপনি কতটা ওভারড্র করতে পারেন), " শেডার সীমা " (আপনার শেডারগুলি কতটা জটিল হতে পারে এবং আপনি তাদের মাধ্যমে কতগুলি ডেটা চাপতে পারেন), " টেক্সচার-ফেচ / টেক্সচার-ব্যান্ডউইথ সীমা " (আপনি কত টেক্সচার ডেটা অ্যাক্সেস করতে পারেন)
এবং, এখন আমরা একটি বড় আসি - যা আপনি সত্যিই জিজ্ঞাসা করছেন - যেখানে সিপিইউ এবং জিপিইউকে ইন্টারেক্ট করতে হবে (বিভিন্ন এপিআই এবং ড্রাইভারের মাধ্যমে)। স্বাচ্ছন্দ্যে এখানে " ব্যাচের সীমা " এবং " ব্যান্ডউইথ " রয়েছে। (দ্রষ্টব্য যে আমি আগে উল্লিখিত ধারাবাহিকের একটি অংশ বিস্তৃত বিবরণে যায় ))
তবে, মূলত, যখনই আপনি কোনও ফাংশন কল করেন (বা এক্সএনএর অংশ, যেমন এটি আপনার জন্য করে ) একটি ব্যাচ ঘটে ( যেমন আপনি ইতিমধ্যে জানেন ) ) আপনি যেহেতু কোনও সন্দেহ ইতিমধ্যে পড়েছেন, আপনি প্রতি ফ্রেমে এর কয়েক হাজার * পান। এটি একটি সিপিইউ সীমা - তাই এটি আপনার অন্যান্য সিপিইউ ব্যবহারের সাথে প্রতিযোগিতা করে। এটি ড্রাইভারটি যা আঁকতে বলেছে তার সবকিছুই প্যাকেজিং করে জিপিইউতে পাঠিয়ে দিচ্ছে।GraphicsDevice.Draw*
SpriteBatch
এবং তারপরে জিপিইউতে ব্যান্ডউইথ রয়েছে । এটি সেখানে আপনি কতটা কাঁচা ডেটা স্থানান্তর করতে পারেন। এতে ব্যাচের সাথে যাওয়া সমস্ত রাজ্যের তথ্য অন্তর্ভুক্ত রয়েছে - DrawUser*
ফাংশনগুলি ব্যবহার করার সময় রেন্ডারিং স্টেট এবং শেডার কনস্ট্যান্টস / পরামিতিগুলি (যার মধ্যে ওয়ার্ল্ড / ভিউ / প্রজেক্ট ম্যাট্রিক্সের মতো জিনিস রয়েছে) নির্ধারণ থেকে শুরু করে সবকিছু । এটিতে টেক্সচার, ভারটেক্স বাফার ইত্যাদিতে SetData
এবং যে কোনও কল অন্তর্ভুক্ত রয়েছে includesGetData
এই মুহুর্তে আমার বলা উচিত যে আপনি যে কোনও কিছুতে কল করতে পারেন SetData
(টেক্সচার, ভার্টেক্স এবং সূচি বাফার, ইত্যাদি) পাশাপাশি Effect
এস - জিপিইউ মেমরিতে রয়ে গেছে। এটি নিয়মিত জিপিইউতে পুনরায় পাঠানো হয় না। একটি অঙ্কন কমান্ড যা তথ্য উল্লেখ করে যে ডেটা কেবলমাত্র সেই তথ্যটিতে পয়েন্টার সহ প্রেরণ করা হয়।
(এছাড়াও: আপনি কেবলমাত্র মূল থ্রেড থেকে অঙ্কন কমান্ড পাঠাতে পারেন তবে আপনি যে SetData
কোনও থ্রেডে পারেন ))
XNA তার রেন্ডার রাষ্ট্র শ্রেণীর (সঙ্গে কিছুটা জিনিষ complicates BlendState
, DepthStencilState
ইত্যাদি)। এই রাষ্ট্রীয় তথ্য প্রতি ড্র কল পাঠানো হয় (প্রতিটি ব্যাচে)। আমি ১০০% নিশ্চিত নই, তবে আমি এই আবেগের মধ্যে আছি যে এটি অলসভাবে প্রেরণ করা হয়েছে (এটি কেবল পরিবর্তিত হয় এমন রাষ্ট্রটি প্রেরণ করে)। যে কোনও উপায়ে, রাষ্ট্র পরিবর্তনগুলি একটি ব্যাচের ব্যয়ের তুলনায় বিনামূল্যে বিন্দুতে সস্তা।
অবশেষে, শেষ কথাটি উল্লেখ করার জন্য হ'ল অভ্যন্তরীণ জিপিইউ পাইপলাইন । আপনি এখনও এটি পড়তে হবে এমন ডেটা বা এটি এখনও লেখার দরকার পড়ে এমন ডেটা পাঠ করে এটি ফ্লাশ করতে বাধ্য করতে চান না। একটি পাইপলাইন ফ্লাশের অর্থ এটি অপারেশনগুলি সমাপ্ত হওয়ার জন্য অপেক্ষা করে, যাতে ডেটা অ্যাক্সেস করার সময় সবকিছু সামঞ্জস্যপূর্ণ অবস্থায় থাকে।
দুটি বিশেষ ক্ষেত্রে লক্ষ্য রাখা উচিত: GetData
গতিশীল কিছুতে কল করা - বিশেষত এমন একটি RenderTarget2D
বিষয়ে যা জিপিইউ লিখতে পারে। এটি পারফরম্যান্সের জন্য অত্যন্ত খারাপ - এটি করবেন না।
অন্য SetData
কেসটি ভার্টেক্স / সূচক বাফারগুলিতে কল করছে। আপনার যদি প্রায়শই এটি করার দরকার হয় তবে একটি DynamicVertexBuffer
(এছাড়াও DynamicIndexBuffer
) ব্যবহার করুন । এটি জিপিইউকে জানতে দেয় যে তারা প্রায়শই পরিবর্তিত হবে এবং পাইপলাইন ফ্লাশ এড়াতে অভ্যন্তরীণভাবে কিছু বাফারিং যাদু করতে পারে।
(এছাড়াও লক্ষ করুন যে গতিশীল বাফারগুলি DrawUser*
পদ্ধতির তুলনায় দ্রুত - তবে তাদের সর্বাধিক প্রয়োজনীয় আকারে প্রাক-বরাদ্দ করতে হবে))
... এবং এটি এক্সএনএ পারফরম্যান্স সম্পর্কে আমি জানি সমস্ত কিছুই :)