سؤال

النظر في هذا السؤال: لماذا يحتاج برنامج التحويل البرمجي C/C ++ إلى معرفة حجم الصفيف في وقت الترجمة؟ لقد وصلني إلى أن المنفذين المترجمون كان ينبغي أن يكون لديهم بعض الأوقات للحصول على أقدامهم الآن (إنه جزء من معيار C99 ، هذا قبل 10 سنوات) وتوفير تطبيقات فعالة.

ومع ذلك ، لا يزال يبدو (من الإجابات) أن تعتبر مكلفة.

هذا بطريقة ما يفاجئني.

بالطبع ، أفهم أن الإزاحة الثابتة أفضل بكثير من الإزاحة الديناميكية من حيث الأداء ، وعلى عكس اقتراح واحد لن يكون لديّ المترجم في الواقع ، تم قياسها ؛)

لكني ما زلت مندهشًا من المفترض كلفة:

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

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

إعادة صياغة

كيف يتم تنفيذ VLAs في GCC / VC ++؟

هل التكلفة حقا مثيرة للإعجاب؟

نهاية إعادة الصياغة

يبدو لي أنه يمكن أن يكون أفضل من استخدام ، على سبيل المثال ، أ vector, ، حتى مع التطبيقات الحالية ، نظرًا لأنك لا تتحمل تكلفة تخصيص ديناميكي (على حساب عدم الإصلاح).

تعديل:

هناك استجابة جزئية هنا, ، ومع ذلك ، فإن مقارنة VLAs مع المصفوفات التقليدية تبدو غير عادلة. إذا عرفنا الحجم مسبقًا ، فلن نحتاج إلى VLA. في نفس السؤال ، قدم أندريه بعض المؤشرات المتعلقة بالتنفيذ ، لكنه ليس دقيقًا كما أريد.

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

المحلول

كيف يتم تنفيذ VLAs في GCC / VC ++؟

AFAIK VC ++ لا ينفذ VLA. إنه برنامج التحويل البرمجي C ++ ويدعم C89 فقط (لا VLA ، لا تقيد). لا أعرف كيف تنفذ GCC VLAs ولكن أسرع طريقة ممكنة هي تخزين المؤشر إلى VLA وحجمه في الجزء الثابت من إطار المكدس. وبهذه الطريقة ، يمكنك الوصول إلى واحدة من VLAs مع أداء صفيف ثابت الحجم (إنه آخر VLA إذا كان المكدس ينمو لأسفل كما هو الحال في x86 (Dereference [مؤشر مكدس + مؤشر*حجم العنصر + حجم آخر دفعات مؤقتة]) ،) ، و VLA الأول إذا كان ينمو للأعلى (dereference [stackFrame Pointer + Offset من stackframe + index*size element])). ستحتاج جميع VLAs الأخرى إلى إحدى الاتجاهات الأخرى للحصول على عنوان الأساس من الجزء الثابت من المكدس.

[ يحرر: أيضًا عند استخدام VLA ، لا يمكن لـ برنامج التحويل البرمجي حذف مؤشر قاعدة المكدس ، وهو أمر زائد على خلاف ذلك ، لأنه يمكن حساب جميع التعويضات من مؤشر المكدس أثناء وقت الترجمة. لذلك لديك سجل واحد أقل مجانا. - نهاية التحرير ]

هل التكلفة حقا مثيرة للإعجاب؟

ليس صحيحا. علاوة على ذلك ، إذا لم تستخدمه ، فلن تدفع ثمنها.

[ يحرر: ربما ستكون إجابة أكثر صحة: بالمقارنة مع ماذا؟ بالمقارنة مع المتجه المخصص للكومة ، سيكون وقت الوصول هو نفسه ولكن التخصيص والتخصيص سيكون أسرع. - نهاية التحرير ]

نصائح أخرى

إذا تم تنفيذها في VC ++ ، فسأفترض أن فريق التحويل البرمجي سيستخدم بعض المتغيرات _alloca(size). وأعتقد أن التكلفة تعادل استخدام المتغيرات ذات المحاذاة الأكبر من 8 بايت على المكدس (مثل __m128) ؛ يتعين على المترجم تخزين مؤشر المكدس الأصلي في مكان ما ، ويتطلب محاذاة المكدس تسجيلًا إضافيًا لتخزين المكدس غير المحدد.

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

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