طريقة فعالة لحفظ البيانات على القرص أثناء تشغيل مهمة حسابية مكثفة

StackOverflow https://stackoverflow.com/questions/1014113

سؤال

أنا أعمل على برنامج علمي يستهلك الكثير من وحدة المعالجة المركزية (يرتبط ببروك)، ولكنه يحتاج إلى كتابة البيانات إلى القرص في كثير من الأحيان (مرتبط بالإدخال/الإخراج).

أقوم بإضافة التوازي إلى هذا (OpenMP) وأتساءل ما هي أفضل طريقة لتلبية احتياجات الكتابة إلى القرص.لا يوجد سبب لانتظار المحاكاة على محرك الأقراص الثابتة (وهو ما تفعله الآن).

أنا أبحث عن "أفضل الممارسات" لهذا الغرض، والسرعة هي أكثر ما أهتم به (يمكن أن تكون هذه عمليات محاكاة طويلة جدًا).

شكرا ~ أليكس

الأفكار الأولى:

وجود عملية منفصلة تقوم بالكتابة الفعلية على القرص وبالتالي فإن المحاكاة لها عمليتان:أحدهما مرتبط بوحدة المعالجة المركزية (المحاكاة) والآخر مرتبط بـ IO (كتابة الملف).هذا يبدو معقدا.

ربما أنبوب / عازلة؟أنا جديد على هذه الأمور، لذا ربما يكون هذا حلاً ممكنًا.

هل كانت مفيدة؟

المحلول

إذا تنفيذ قانون الزواج إلى البرنامج الخاص بك، فمن الأفضل استخدام <القوي> #pragma المرصد المغربي للسجون واحد أو <القوي> #pragma المرصد المغربي للسجون رئيسية من قسم مواز لحفظ إلى ملف. هذه pragmas يسمح مؤشر واحد فقط لتنفيذ شيء. لذا، كنت رمز قد تبدو على النحو التالي:

#pragma omp parallel
{
    // Calculating the first part
    Calculate();

    // Using barrier to wait all threads
    #pragma omp barrier

    #pragma omp master
    SaveFirstPartOfResults();

    // Calculate the second part
    Calculate2();

    #pragma omp barrier

    #pragma omp master
    SaveSecondPart();

    Calculate3();

    // ... and so on
}
سوف

وهنا فريق من المواضيع تفعل الحساب، ولكن موضوع واحد فقط حفظ النتائج على القرص.

ويبدو خط أنابيب البرمجيات. أقترح عليك أن تنظر في نمط TBB :: خط أنابيب من مكتبة إنتل خيوط كتل البناء. أنا قد يحولك إلى البرنامج التعليمي على خطوط الأنابيب البرمجيات على الموقع http://cache-www.intel.com/cd/00/00/30/11/301132_301132.pdf#page=25 . يرجى قراءة الفقرة 4.2. أنها تحل المشكلة: موضوع واحد على القراءة من القرص، والثانية لمعالجة قراءة الجمل، وثلث لإنقاذ لدفع

.

نصائح أخرى

وأنا أقول أن أفضل طريقة ليكون تفرخ موضوع مختلف لحفظ البيانات، وليس عملية جديدة تماما. مع عملية جديدة، تقوم بتشغيل عناء للاتصال البيانات ليتم حفظها عبر الحدود العملية التي يقدم مجموعة جديدة من الصعوبات.

الحل الأول الذي يتبادر إلى الذهن هو ما قلته تقريبًا - وهو كتابة القرص في عمليته الخاصة باستخدام أنبوب أحادي الاتجاه من بطاقة sim إلى الكاتب.يكتب الكاتب بأسرع ما يمكن (يسحب بيانات جديدة من الأنابيب).تكمن المشكلة في ذلك في أنه إذا تقدمت بطاقة sim كثيرًا على الكاتب، فسيتم حظر بطاقة sim على توجيه الإخراج على أي حال، وسيتم ربط الإدخال/الإخراج عند إزالة واحدة.

المشكلة هي أن دورة المحاكاة الخاصة بك لا تكتمل في الواقع إلا بعد ظهور النتائج.

الشيء الثاني الذي يتبادر إلى ذهني هو استخدام الإدخال/الإخراج غير المحظور.عندما تحتاج بطاقة sim إلى الكتابة، يجب أن تفعل ذلك عبر الإدخال/الإخراج غير المحظور.عند الحاجة التالية للكتابة، يمكنه بعد ذلك التقاط نتائج عملية الإدخال/الإخراج السابقة (ربما تتطلب انتظارًا صغيرًا) قبل بدء العملية الجديدة.يؤدي ذلك إلى استمرار تشغيل المحاكاة قدر الإمكان بالتوازي مع الإدخال/الإخراج دون السماح للمحاكاة بالتقدم كثيرًا في الكتابة.

سيكون الحل الأول أفضل إذا كانت دورة معالجة المحاكاة تختلف (أحيانًا أصغر من وقت الكتابة، وأحيانًا أطول) لأنه في المتوسط، قد تتماشى عمليات الكتابة مع المحاكاة.

إذا كانت دورة المعالجة دائمًا (أو دائمًا تقريبًا) ستكون أقصر من وقت الكتابة ، فقد لا تهتم بالأنبوب واستخدام I/O فقط ، لأنه إذا كنت تستخدم الأنبوب ، فسيتم تملأه في النهاية وسوف يتم تعليق SIM على I/O على أي حال.

ومنذ كنت وحدة المعالجة المركزية وIO ملزمة: اسمحوا لي أن أخمن: لا يزال هناك الكثير من الذاكرة المتوفرة، أليس كذلك

وإذا كان الأمر كذلك يجب أن المخزن المؤقت البيانات التي يجب أن تكون مكتوبة على القرص في الذاكرة إلى بعض تمديد. كتابة أجزاء ضخمة من البيانات عادة ما تكون أسرع بكثير من كتابة قطع صغيرة.

لكتابة نفسها: النظر في استخدام الذاكرة المعينة IO. انها كانت فترة من الوقت منذ ان كنت قياسها، ولكن آخر مرة فعلت ذلك كان كبيرا بشكل أسرع.

وأيضا يمكنك التجارة دائما من وحدة المعالجة المركزية مقابل IO قليلا. أعتقد أنك حاليا كتابة البيانات على انها نوع من البيانات الخام، غير مضغوط، أليس كذلك؟ قد تحصل على بعض أداء IO إذا كنت تستخدم نظام ضغط بسيط للحد من كمية البيانات المراد كتابتها. مكتبة ZLIB من السهل جدا للعمل مع والكمادات سريع جدا على أدنى مستوى الضغط. ان ذلك يعتمد على طبيعة البيانات الخاصة بك، ولكن إذا كان هناك الكثير من التكرار في ذلك حتى خوارزمية ضغط بسيطة جدا قد القضاء على مشكلة IO ملزمة.

واحد موضوع تنفيذ باستمرار خطوة من عملية حسابيا كثيفة ثم يضيف نتيجة جزئية لطابور من النتائج الجزئية. موضوع آخر يزيل باستمرار النتائج الجزئية من قائمة الانتظار ويكتب لهم إلى القرص. تأكد من مزامنة الوصول إلى قائمة الانتظار. طابور A هو بنية بيانات القائمة تشبه حيث يمكنك إضافة عناصر إلى النهاية وإزالة عناصر من الجبهة.

اجعل طلبك يحتوي على اثنين الخيوط, واحد لوحدة المعالجة المركزية والآخر للقرص الصلب.

اطلب من مؤشر ترابط وحدة المعالجة المركزية دفع البيانات المكتملة إلى قائمة الانتظار التي يسحبها مؤشر ترابط القرص الثابت منها عند وصول البيانات.

بهذه الطريقة تتخلص وحدة المعالجة المركزية من البيانات وتسمح لشخص آخر بالتعامل معها وينتظر القرص الصلب بصبر أي بيانات في قائمة الانتظار الخاصة به.

من ناحية التنفيذ، يمكنك القيام بقائمة الانتظار كنوع من كائنات الذاكرة المشتركة، ولكن أعتقد أن الأنبوب سيكون بالضبط ما تبحث عنه.تقوم وحدة المعالجة المركزية ببساطة بالكتابة إلى الأنبوب عند الحاجة.على جانب القرص الصلب، ما عليك سوى قراءة الأنبوب وكلما حصلت على بيانات صالحة، تابع من هناك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top