হাস্কেল থ্রেডগুলি কেবল 22 এমবি মোট মেমরি ব্যবহার সত্ত্বেও গাদা ওভারফ্লো হয়েছে?


114

আমি একটি রে-ট্রেসারকে সমান্তরাল করার চেষ্টা করছি। এর অর্থ আমার কাছে ছোট ছোট কম্পিউটারের একটি দীর্ঘ তালিকা রয়েছে। ভ্যানিলা প্রোগ্রামটি একটি নির্দিষ্ট দৃশ্যে .9 67.৯৮ সেকেন্ডে এবং মোট 13 মেমরি ব্যবহার এবং 99.2% উত্পাদনশীলতার মধ্যে চলে।

আমার প্রথম প্রয়াসে আমি parBuffer50 টি বাফার আকারের সাথে সমান্তরাল কৌশলটি ব্যবহার করেছি I আমি বেছে নিয়েছিলাম parBufferকারণ এটি তালিকায় চলে কেবল স্পার্কগুলি যত দ্রুত খাওয়া যায় তত দ্রুত তালিকার মেরুদণ্ডকে চাপ দেয় না parList, যা প্রচুর স্মৃতি ব্যবহার করবে যেহেতু তালিকাটি খুব দীর্ঘ। এর সাথে -N2, এটি 100.46 সেকেন্ডের সময় এবং মোট স্মৃতি ব্যবহারের 14 এমবি এবং 97.8% উত্পাদনশীলতার সময়ে চলেছিল। স্পার্ক তথ্যটি হ'ল:SPARKS: 480000 (476469 converted, 0 overflowed, 0 dud, 161 GC'd, 3370 fizzled)

ফিজল স্পার্কগুলির বৃহত অনুপাত ইঙ্গিত দেয় যে স্পার্কগুলির গ্রানুলারিটি খুব কম ছিল, তাই পরবর্তী আমি কৌশলটি ব্যবহার করার চেষ্টা করেছি parListChunk, যা তালিকে খণ্ডে বিভক্ত করে এবং প্রতিটি খণ্ডের জন্য একটি স্পার্ক তৈরি করে। আমি এর এক অংশের আকারের সাথে সেরা ফলাফল পেয়েছি 0.25 * imageWidth। প্রোগ্রামটি 93.43 সেকেন্ড এবং 236 এমবি মোট স্মৃতি ব্যবহার এবং 97.3% উত্পাদনশীলতায় চলেছিল। স্ফুলিঙ্গ তথ্য হল: SPARKS: 2400 (2400 converted, 0 overflowed, 0 dud, 0 GC'd, 0 fizzled)। আমি বিশ্বাস করি যে বৃহত্তর মেমরির ব্যবহার হ'ল কারণ parListChunkতালিকার মেরুদণ্ডকে জোর করে।

তারপরে আমি আমার নিজের কৌশলটি লেখার চেষ্টা করেছি যা অলসভাবে তালিকাটিকে খণ্ডগুলিতে বিভক্ত করেছিল এবং তারপরে খণ্ডগুলিতে পাস parBufferকরে ফলাফলগুলিকে একত্রিত করে ।

 concat $ withStrategy (parBuffer 40 rdeepseq) (chunksOf 100 (map colorPixel pixels))

এটি 95.99 সেকেন্ডে চলেছিল এবং মোট মেমরি ব্যবহারের 22 এমবি এবং 98.8% উত্পাদনশীলতা। এটি এই অর্থে সফল হয়েছিল যে সমস্ত স্পার্ক রূপান্তরিত হচ্ছে এবং মেমরির ব্যবহার অনেক কম, তবে গতির উন্নতি হয়নি। এখানে ইভেন্টলগ প্রোফাইলের অংশের একটি চিত্র রয়েছে।ইভেন্ট লগ প্রোফাইল

আপনি দেখতে পাচ্ছেন হ্যাপের ওভারফ্লোর কারণে থ্রেডগুলি বন্ধ হয়ে যাচ্ছে। আমি যুক্ত করার চেষ্টা করেছি +RTS -M1Gযা 1 জিবি পর্যন্ত পুরোপুরি ডিফল্ট হ্যাপের আকার বাড়িয়ে তোলে। ফলাফল পরিবর্তন হয়নি। আমি পড়েছি যে হ্যাস্কেল মূল থ্রেডটি স্ট্যাকটি ওভারফ্লো হয়ে গেলে হিপ থেকে স্মৃতি ব্যবহার করবে, তাই আমি ডিফল্ট স্ট্যাকের আকারটিও বাড়িয়ে দেওয়ার চেষ্টা করেছি +RTS -M1G -K1Gতবে এর কোনও প্রভাবও ছিল না।

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

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

সম্পাদনা 2: এই প্রশ্নের জন্য উত্সর্গীকৃত গিথুব রেপোর লিঙ্ক এখানে । আমি প্রোফাইলিং ফোল্ডারে প্রোফাইলিং ফলাফলগুলি অন্তর্ভুক্ত করেছি।

সম্পাদনা 3: এখানে কোডের প্রাসঙ্গিক বিটটি দেওয়া হল:

render :: [([(Float,Float)],[(Float,Float)])] -> World -> [Color]
render grids world = cs where 
  ps = [ (i,j) | j <- reverse [0..wImgHt world - 1] , i <- [0..wImgWd world - 1] ]
  cs = map (colorPixel world) (zip ps grids)
  --cs = withStrategy (parListChunk (round (wImgWd world)) rdeepseq) (map (colorPixel world) (zip ps grids))
  --cs = withStrategy (parBuffer 16 rdeepseq) (map (colorPixel world) (zip ps grids))
  --cs = concat $ withStrategy (parBuffer 40 rdeepseq) (chunksOf 100 (map (colorPixel world) (zip ps grids)))

গ্রিডগুলি এলোমেলোভাবে ভাসমান যা প্রাকপম্পিউটেড এবং রঙিন পিক্সেল দ্বারা ব্যবহৃত হয় The এর ধরণটি colorPixelহ'ল:

 colorPixel :: World -> ((Float,Float),([(Float,Float)],[(Float,Float)])) -> Color

2
আপনি যেখানে চেষ্টা করেছিলেন ঠিক সেই প্রতিশ্রুতি দিতে পারেন concat $ withStrategy …? আমি এই আচরণটি পুনরুত্পাদন করতে পারি না 6008010, এটি আপনার সম্পাদনার নিকটতম প্রতিশ্রুতি।
জেতা

3
আমি একটি উত্সর্গীকৃত রেপো তৈরি করেছি যাতে আমি দুর্ঘটনাবশত এর মধ্যে গণ্ডগোল না করি। আমি সমস্ত প্রোফাইল তথ্য অন্তর্ভুক্ত করেছি।
জাস্টিন রেমন্ড

@ ডিফিউয়ার যখন আমি নিজের কৌশলটি সংজ্ঞায়িত করার কথা বলতে চাইছিলাম তখন তার অর্থ নয় Strategy। একটি ভাল শব্দ বাছাই করা উচিত ছিল। এছাড়াও, গাদা ওভারফ্লো ইস্যু ক্ষেত্রেও একই ঘটনা ঘটে parListChunkএবং parBufferখুব।
জাস্টিন রেমন্ড

উত্তর:


2

আপনার সমস্যার সমাধান নয়, তবে কারণটির জন্য একটি ইঙ্গিত:

হাস্কেল মনে হয় স্মৃতি পুনঃব্যবহারে খুব রক্ষণশীল এবং দোভাষী যখন একটি মেমরি ব্লক পুনরায় দাবি করার সম্ভাবনা দেখেন তখন এটি তার পক্ষে যায়। আপনার সমস্যার বিবরণটি এখানে (নীচে) বর্ণিত নাবালিক জিসি আচরণের সাথে খাপ খায়: https://wiki.haskell.org/GHC/Memory_Management

512kb "নার্সারি" এ নতুন ডেটা বরাদ্দ করা হয়েছে। একবার ক্লান্ত হয়ে গেলে, "মাইনর জিসি" ঘটে - এটি নার্সারিটি স্ক্যান করে এবং অব্যবহৃত মানকে মুক্ত করে।

সুতরাং যদি আপনি ডেটাটি ছোট অংশগুলিতে কাটা থাকেন তবে আপনি ইঞ্জিনটিকে ক্লিনআপটি পূর্বে করতে সক্ষম করবেন - জিসি কিক ইন।

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