سؤال

لذا ، أجد إيغن تعطل الحزمة عندما أحاول إعلان مصفوفة أكبر من 10000x10000. أحتاج إلى إعلان مصفوفة كهذه .. حوالي 13000 × 3000 عنصر بشكل موثوق. أجرت اختبارًا مثل:

for( int tortureEigen = 1 ; tortureEigen < 50000 ; tortureEigen++ )
{
  printf( "Torturing Eigen with %dx%d..\n", tortureEigen, tortureEigen ) ;
  Eigen::MatrixXd m( tortureEigen, tortureEigen ) ;
}

تحطم على الجهاز الخاص بي (6 جيجابايت ذاكرة الوصول العشوائي) في 14008 عناصر.

أنا محبط نوعًا ما! اعتقدت أن Eigen كان مثل Matlab أو Octave ويجب ألا تصطدم باستخدام صفائف أكبر ، حتى لو كان يضرب القرص أو شيء من هذا القبيل ..

والأكثر من ذلك هو عندما أقوم بتشغيل هذا الاختبار وأبقي Taskman مفتوحًا ، فإن العملية التي تقوم بإنشاء هذه المصفوفات لا تستخدم حتى الكثير من الذاكرة. تقارير Taskman تحت 2K الاستخدام.

باستخدام إصدار Eigen 2.0.15 مستقر

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

المحلول 2

جميع الإجابات هنا مفيدة!

لقد أتضح أن عند تجميعها ك 32 بت التطبيق ، سوف يعطل eigen إذا حاولت أن تعلن أ Matrixxd كثيف, ، كما كنت ، أكبر من 14000 عنصر أو نحو ذلك. يحدث الحادث مع _aligned_malloc لا يمكن تخصيص إرجاع 0 في رمز eigen lex (matrixxd :: desize ()) ، وهذا يعني 1.5 جيجابايت من ذاكرة الوصول العشوائي المتجاورة المحاذاة تحت 32 بت ، وهذا أمر منطقي ، لأن هذا يقترب من نصف الحد الأقصى لذاكرة Loc . إن العثور على أكثر من 1.5 جيجابايت متجاورة من 4.0 يصبح غير مرجح حقًا ، أفترض! الترقية إلى Eigen 3.0 للأسف لا حل المشكلة.

الحل #1

حسنًا ، لذلك قمت بتجميعها في 64 بت ، وعلى جهاز 6 جيجا بايت ، يعمل البرنامج بنجاح ، مع تخصيص MatrixXD الكثيف والحل الذي يعمل بشكل جيد.

الحل #2

حل آخر هو استخدام أ DynamicSparseMatrix<double>. لا يتعطل Sparse على التخصيص الضخم للحجم ، حتى مع تطبيق 32 بت ، لكن دعم API لحل قصة أخرى (يبدو أن API ترغب في التحويل إلى نوع كثيف MatrixxD من أجل حلها ، مما يتركنا نفس المشكلة الأصلية.)

نصائح أخرى

مطور Eigen هنا. من الأفضل لك طرح أسئلة eigen على قنوات الدعم الخاصة بنا على سبيل المثال Forum ... ؛-)

إجابة قصيرة: هل تستخدم مصفوفات ثابتة أو ديناميكية؟

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

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

من مستند Eigen:

كثيف مقابل متناثر: هذه الفئة المصفوفة تتعامل مع المصفوفات والمتجهات الكثيفة ، وليس المتجهات المتفرقة. للاطلاع على المصفوفات والمتجهات المتفرقة ، انظر الوحدة النمطية المتفرقة.
المصفوفات والمتجهات الكثيفة هي صفائف معتادة من المعاملات. يتم تخزين جميع المعاملات ، في صفيف متجاورة عادية. هذا على عكس المصفوفات والمتجهات المتفرقة حيث يتم تخزين المعاملات كقائمة من معاملات غير صفرية.

دعنا نرى ، 10000x10000x8 (مصفوفة مزدوجة) يجعل حوالي 1.5 جيجابايت. هذا هو الحد الأقصى لحجم كتلة كومة Continuos تحت نظام التشغيل 32bit ، يتوقع المرء. جرب المصفوفات المتفرقة.

إذا كنت بحاجة حقًا إلى مثل هذه المصفوفات الكثيفة الكبيرة ، فستواجه بعض المشكلات الأخرى: هل سينتهي الحساب قبل انقطاع التيار الكهربائي التالي؟

بالنظر إلى مواصفاتك الصلبة ، لا يمكنني إلا أن أفترض أنك تعمل على نظام التشغيل 64 بت.

لا يزال بإمكانك التعطل حتى إذا تم تنظيم الذاكرة إلى ملف الصفحة. قد يعني أن الذاكرة مجزأة ، أو أن ملف صفحتك لا يزال صغيرًا جدًا. إذا كان الأمر كذلك ، فيجب عليك رفع ملف صفحتك إلى شيء كبير مثل 8 أو 12 جيجابايت أو نحو ذلك.

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