Withক্যের সাথে গেমস তৈরির সময় আমার কীভাবে জিসির কাছে অ্যাকাউন্টিং করা উচিত?


15

* যতদূর আমি জানি, আইওএসের জন্য ইউনিটি 3 ডি মনো-রানটাইম ভিত্তিক এবং মনোতে কেবল প্রজন্মের চিহ্ন এবং সুইপ জিসি রয়েছে।

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

সুতরাং, বিশাল পারফরম্যান্স হ্রাস না করে ইউনিটি 3 ডি ব্যবহার করার সময় আমি কীভাবে এই জিসি সময় এড়াতে পারি?


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

উত্তর:


18

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

যদি আপনার গেমটি সহজ হয় তবে জিসি এটি ঠিকঠাকভাবে পরিচালনা করতে পারে তবে এখানে কয়েকটি পয়েন্টার রয়েছে যা আপনি দেখতে চাইতে পারেন।

অকাল অপটিমাইজেশন

প্রথমে নিশ্চিত করে নিন এটি ঠিক করার চেষ্টা করার আগে এটি আসলে আপনার জন্য সমস্যা।

পুলিং ব্যয়বহুল রেফারেন্স প্রকারগুলি

আপনার প্রায়শই তৈরি হওয়া রেফারেন্সের ধরণের আপনার উচিত, বা যার গভীর কাঠামো রয়েছে। প্রত্যেকটির উদাহরণ হ'ল:

  • প্রায়ই তৈরী করা হয়েছে: একটি Bulletএকটি বস্তুর বুলেট-জাহান্নাম খেলা
  • গভীর কাঠামো: একটি এআই বাস্তবায়নের জন্য সিদ্ধান্ত গাছ।

Stackআপনার পুল হিসাবে এটি ব্যবহার করা উচিত (বেশিরভাগ বাস্তবায়ন যা এ ব্যবহার করে এর বিপরীতে Queue)। এর কারণ হ'ল Stackযদি আপনি পুলটিতে কোনও বস্তু ফিরিয়ে দেন এবং তাৎক্ষণিকভাবে অন্য কোনও জিনিস এটি ধরে ফেলে; এটির সক্রিয় পৃষ্ঠায় থাকার অনেক বেশি সম্ভাবনা থাকবে - বা আপনি ভাগ্যবান হলে এমনকি সিপিইউ ক্যাশেও। এটা ঠিক যে সামান্য বিট দ্রুত। তদাতিরিক্ত আপনার পুলগুলি সর্বদা আকার-সীমাবদ্ধ করুন (আপনার সীমা অতিক্রম করা হলে কেবল 'চেকিনগুলি উপেক্ষা করুন)।

এগুলি সাফ করার জন্য নতুন তালিকাগুলি তৈরি করা এড়িয়ে চলুন

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

সম্ভব যেখানে স্ট্রাক্ট অ্যারে (বা তালিকা) ব্যবহার করুন

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

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

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

GC.Collect ()

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

আইডিস্পোজেবল এবং ফিল্ড নুলিং

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

নিম্নলিখিত উদাহরণটি ধরুন:

MyObject (G1) -> MyNestedObject (G1) -> MyFurtherNestedObject (G1)
// G1 Collection
MyNestObject (G2) -> MyFurtherNestedObject (G2)
// G2 Collection
MyFurtherNestedObject (G3)

যদি MyFurtherNestedObjectকোনও মাল্টি-মেগাবাইট অবজেক্ট থাকে তবে আপনি গ্যারান্টিযুক্ত হতে পারেন জিসি বেশিক্ষণ এটি দেখবেন না - কারণ আপনি অজান্তেই এটি জি 3 তে প্রচার করেছেন। এই উদাহরণের সাথে এর বিপরীতে:

MyObject (G1) -> MyNestedObject (G1) -> MyFurtherNestedObject (G1)
// Dispose
MyObject (G1)
MyNestedObject (G1)
MyFurtherNestedObject (G1)
// G1 Collection

ডিসপোজার প্যাটার্ন আপনাকে অবজেক্টগুলিকে তাদের ব্যক্তিগত ক্ষেত্রগুলি সাফ করার জন্য অনুমানযোগ্য উপায় সেট আপ করতে সহায়তা করে। উদাহরণ স্বরূপ:

public class MyClass : IDisposable
{
    private MyNestedType _nested;

    // A finalizer is only needed IF YOU CONTROL UNMANAGED RESOURCES
    // ~MyClass() { }

    public void Dispose()
    {
       _nested = null;
    }
}

1
আপনি কি ডাব্লুটিএফ-এর সম্পর্কে উইন্ডোজে .NET ফ্রেমওয়ার্ক একেবারে জেনারাল। এমনকি তাদের ক্লাসে গেটগেনারেশন পদ্ধতি রয়েছে।
ডেড এমজি

2
উইন্ডোজ .NET একটি জেনারেশনাল আবর্জনা সংগ্রাহক ব্যবহার করে, তবে ডাব্লুপি 7 এবং এক্সবক্স 360 তে ব্যবহৃত নেট নেট কমপ্যাক্ট ফ্রেমওয়ার্কটি আরও সীমাবদ্ধ জিসি রয়েছে, এটি ফ্ল্যাট তালিকার চেয়ে সম্ভবত এটি সম্পূর্ণ জেনারাল নয়।
রায় টি।

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

1
@RoyT। উপরের মন্তব্য দেখুন। আমি নির্দেশিত করেছি যে একটি কণার সিস্টেমের মতো - অ্যারেতে বড় লাইনারের পরিমাণের জন্য স্ট্রাক্টগুলি ভাল। আপনি যদি অ্যারেতে জিসি স্ট্রাক্ট সম্পর্কে উদ্বিগ্ন হন তবে যাওয়ার উপায়; কণার মত ডেটা জন্য।
জোনাথন ডিকিনসন

10
@ ডেড এমজিও ডাব্লুটিএফ খুব খারাপভাবে বিবেচিত হয়েছে - বিবেচনা করে আপনি আসলে উত্তরটি সঠিকভাবে পড়েননি। দয়া করে আপনার মেজাজ শান্ত করুন এবং এর মতো একটি সাধারণভাবে আচরণ করা সম্প্রদায়ের মধ্যে ঘৃণ্য মন্তব্য লেখার আগে উত্তরটি পুনরায় পড়ুন।
জোনাথন ডিকিনসন

7

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

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

আপনি নির্দিষ্ট সময়ে আবর্জনা সংগ্রহের জন্য জোর করতে পারেন, যা সাহায্য করতে পারে বা নাও পারে: এখানে কিছু পরামর্শ দেখুন: http://une3d.com/support/docamentation/Manual/iphone- অপ্টিমাইজিং- স্ক্রিপ্টস html


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

না, আপনার জিসি জোর করার কারণগুলির ব্যাখ্যা দেওয়া উচিত কারণ আপনি আমার চেয়ে এটি সম্পর্কে আরও জানেন। :) তবে মনে রাখবেন যে মনো জিসি অগত্যা মাইক্রোসফ্ট জিসির মতো নয় এবং ঝুঁকিগুলিও একই রকম নাও হতে পারে।
কাইলোটন

তবুও, +1। আমি এগিয়ে গিয়েছিলাম এবং জিসির সাথে কিছু ব্যক্তিগত অভিজ্ঞতার বিবরণ দিয়েছিলাম - যা আপনাকে আকর্ষণীয় মনে হতে পারে।
জোনাথন ডিকিনসন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.