الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

داخل أروقة مترجمات ++c, أي الطريقتين أسرع ؟!(global vs local variables)

مغلق
بدأه Khaled.Alshaya في 26 يناير 2008 · 45 رد · 4,502 مشاهدة · في اختبر قداراتك
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ,,

كما تعودنا دائماً في عالم لمحات ++C :)

سنأتي اليوم بسؤال قد يبدو بسيطاً في البداية و لكنه يحمل الكثير من الفائدة و الممارسة البرمجية الجيدة في المستقبل,

موضوعنا اليوم هو حول المتغيرات العامة global variables و المتغيرات المحلية local variables.

لا أعتقد أن أحداً معنا في القسم, لا يعرف ما هي الفرق بين الاثنتين, و لو بشكل بسيط على الأقل, لأنها من الأساسيات التي لا يمكن البرمجة بدونها,

و لكننا اليوم سندخل قليلاً في بعض التفاصيل التي تحدث خلال ترجمة الكود, لنتعرف على فرق جديد بين الاثنتين,

لو تخيلنا أن لدينا حلقة, هذه الحلقة تتكرر لمدة 4294967295 :P مرة, حسناً الحلقة وضعت للتجربة فقط و السؤال ليس عليها :rolleyes: الآن سأعرض طريقيتين متطابقتين لكتابة الحلقة (البسيطة جداً) :

for( unsigned int i = 0; i < 4294967295; i++ );

الطريقة الثانية ستكون كالتالي :

unsigned i;

int main(){
	for( i = 0; i < 4294967295; i++ );
	return 0;
}

انظر إلى المتغير i حيث عرفناه مرة داخل الـ for loop و مرة كمتغير عام global variable ,,

العملية الأساسية التي ستحدث داخل الحلقة هي العملية التالية :

i++

السؤال الآن أي الطريقتين أسرع و لماذا ؟ :thumbup:

تحياتي ,,

#2

بناء على التجربة الـ Global أسرع لكن لا أعرف لماذا والصراحة ليس من المنطقي أن يكون الـ Global أسرع :blink:

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#3

لا ارى سبب لا ختلاف السرعة!

tvquran_6.gif

#4

لا أعتقد أنه سوف يكون هناك إختلاف في السرعه .

لماذا ؟ لأن المترجم عندما يحول الكود إلى (أسمبلي) فإن كل المتغيرات المحجوزه تكون في قسم واحد مع بعضها بغض النظر عن كونها محليه أو (دوليه) أو حتى (إقليمية) , هذا حسب ما أعتقد وهو بالأغلب صحيح

.data
iGlobal DB 0
iLocal DB 0

هذا والله أعلم

#5

السلام عليكم ..

بصراحه يا اخ خالد .. لم انتبه في يوم ما الى وجود فرق في السرعات بين المتغيرين وايضا بصراحه اخرى انا قليل التعامل مع المتغيرات العامه.. ولسبب خطورتها على البرنامج .. حيث ان استعمال المتغير العام في اي مكان من البرنامج فان قيمته تتغير .. وهذا يؤدي الى بطئ على حد ما اتوقع ..

ولسبب هذه الخطورة فاتوقع ولست متاكدا من ان المتغير المعرف داخل الدوارة سيكون اسرع ..

وسبب اخر وهو ان المتغير العام يأخذ القيمة الابتدائية له تلقائيا من قبل النظام او من قبل المترجم .. اي انه عند كتابة الكود التالي ..

 int i;

   main()
   {
	   i++;
   }

فان المترجم تلقائيا سيعطي قيمة ابتدائيه للمتغير العام i وهي صفر .. لكي نستطيع التعامل معه في اي جزء من البرنامج وهو يحتوي على قيمة لا تتاثر عند تغيرها وهي الصفر ..

والقيم الابتدائيه تحدد للمتغيرات العامه حسب الجدول التالي ..

int	 0  
char	 '\0'  
float	 0  
pointer	NULL

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

لذلك فللسببين الذين ذكرتهما اعلاه اتوقع ان الكود الذي يعرف به المتغير المحلي اسرع ..

هذا جوابي وتحليلي والله اعلم .. واذا كان خاطئا اتمنى ان تشرح الفرق بينهما في الكودين اعلاه ..

اسجل اعجابي بمواضيعك اخي خالد .. بارك الله فيك على مجهودك ...

طبعا انا اواجه الان امتحانات تجعلني اتاخر في الدخول الى المنتدى .. ولكن ان شاءاالله سانتهي منها بعد اسبوع واعود اليكم محملا باشياء مفيدة ان شاءالله ...

تحياتي العطرة ..

تم تعديل هذه المشاركة بواسطة سنان محمد صالح في 26 يناير 2008 في 21:59

يَارَبُ إِن ضَاقَت قُلُوُب الْنَّاسٍ عَنْ مّافِي .. مِنْ خَيْرٍٍ فَعَفْوكَ لَا يَضِيْقْ ..

#6

السلام عليكم

مشاركة سريعة جداً...

الglobal اسرع لانك تعطية قيمة صفر اول مرة والمرة الثانية تقوم بتغير القيمة لواحد والمراة الثالثة لإثنين وهكذا..

اما الlocal فانت تقوم بإعطائه القمية صفر وفى الدورة الثانية تعطية القيمة صفر ثم تقوم بتغيرها لواحد, والمرة الثالثة تعيد الكرة وتعطية القمية صفر ثم تقوم بتغيرها لاثنين وهكذا..

بإختصار فى الglobal تقوم بتعريف المتغير مرة واحدة فقط, اما فى الlocal فانت تقوم بتعريف المتغير مرة كل دورة...

والسلام عليكم

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

#7

السﻻم عليكم,

-ﻻ يا أخى أحمد ال for بتعمل initialization للمتغير مرة واحدة بس.

-بالنسبة للسؤال فأنا بصراحة معرفش بس ممكن نألف :D, ال global variables أكيد مش بتتحجز فى ال stack و بالتالى علشان ندخلها مش عايزين stack pointer و البروسيسور مش حيحسب ال offset اللى حيروح يجيبها منه لكن أعتقد حيبقى مخزن ال direct address بتاع المتغير, علشان كدة ال access لل global أعتقد إنه حيبقى أسرع.

والله أعلم.

#8

المشكلة يا أخ Blueteeth أن الدوال تضع قيم المتغيرات الـ Local في الـ Stack عندما يتحول مسار البرنامج إلى دالة أخرى وفي حالتنا تلك فإن الـ Loop لن تضع شيئا في الـ Stack حتى تنتهي وعندما تنتهي من المفترض أن المتغير سيتم محوه أصلا لأن الـ Loop قد انتهت ولم يعد لهذا المتغير أي استخدام

هذا أيضا تأليف للعلم بالشئ :lol: لكن يبدو مقنعا أليس كذلك ؟!!!

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#9

:D أخى الكريم باسم, الدوال تضع متغيراتها ال local فى ال stack على أى حال سواء تم تغيير مسار البرنامج إلى دالة أخرى أو لا. لذلك ال i موجودة فى ال stack الخاصة بالبرنامج أيضا.

#10

السلام عليكم ,,

أولاً طريقة تفكيركم هي نفس طريقة تفكيري يوم أن تلقيت و السؤال و حتى بعد أن أجبت عنه قبل أن أرى الإجابة عليه :D

الحقيقة أن استخدام متغير محلي أسرع من استخدام متغير global في هذه الحالة(في أغلب الحالات أيضاً و لكن ليس كلها ) :huh:

لماذا ؟؟؟؟؟؟؟؟؟؟

في ++C المتغيرات العامة تكون في الذاكرة دائماً! أما المتغير i فلن يكون على الـ stack بل سيكون في أحد الـ registers الخاصة بالمعالج :P

بكل تأكيد لن يكون هناك فرق ملموس بالنسبة لنا على الأقل, و لكن التعامل مع المسجلات الخاصة بالمعالج أسرع بكثير من التعامل مع الذاكرة.

أن أتكلم عن المعالجات بشكل عام و هناك بعض المعالجات التي تحتوي على counters عبارة عن register و بالتالي تصبح العملية على مستوى المعالج نفسه و لا يحتاج إلى الذهاب و العودة للذاكرة كل مرة. هذا باختصار و لكن هناك حالات لا يكون هناك فرق بين الطريقتين عندما يكون المتغير المحلي على الـ stack, هل تعرفون متى يمكن أن يحصل هذا ؟ B)

سأعود للتعليق على الردود و لكن بعد فاصل قصير .

تحياتي ,,

#11

ممم بس أعتقد موضوع وضع المتغيرات فى ال registers دا راجع كليا للكومبايلر, حتى مع كلمة register فأنت لا تضمن أن ال run-time فعلا سيضعه فى ال registers.

يعنى أنا لو بستخدم متغير عام كمتغير للوب (بدل ال i يعنى), هل سيظل بالذاكرة برضه؟

#12

أخ خلدون,

اقتباس
لماذا ؟ لأن المترجم عندما يحول الكود إلى (أسمبلي) فإن كل المتغيرات المحجوزه تكون في قسم واحد مع بعضها بغض النظر عن كونها محليه أو (دوليه) أو حتى (إقليمية) , هذا حسب ما أعتقد وهو بالأغلب صحيح

صحيح أن المتغيرات تحجز ككتل مع بعضها البعض, فإن المترجمات تفضل استخدام مسجلات المعالج بدلاً من حجز الذاكرة إذا استطاعت فعل ذلك.

أخ سنان,

في لغات أخرى على ما أعتقد, هناك default initialization values, كصفر للأعداد و NULL للكائنات و هكذا,

و لكن في ++C إذا لم تعطي قيمة للمتغير وقت حجزه فإنه سيحمل garbage من الذاكرة,

أي أن كل مايحدث في ++C هو عملية حجز مكان الذاكرة, و بكل تأكيد سيكون هذا المكان مستعملاً قبلاً,

و لن تقوم ++C بتغيير القيمة القديمة حتى تقوم بذلك أنت يدوياً :wacko:

أستاذ أحمد,

اقتباس
الglobal اسرع لانك تعطية قيمة صفر اول مرة والمرة الثانية تقوم بتغير القيمة لواحد والمراة الثالثة لإثنين وهكذا..

اما الlocal فانت تقوم بإعطائه القمية صفر وفى الدورة الثانية تعطية القيمة صفر ثم تقوم بتغيرها لواحد, والمرة الثالثة تعيد الكرة وتعطية القمية صفر ثم تقوم بتغيرها لاثنين وهكذا..

بإختصار فى الglobal تقوم بتعريف المتغير مرة واحدة فقط, اما فى الlocal فانت تقوم بتعريف المتغير مرة كل دورة...

الموضوع مربك قليلاً, لأن كتب ++C لا تشير إلى الـ for loop كثيراً عن الحديث عن لـ scopes ,

و لكن بشكل عام عند الكلام عن for فهناك ثلاث scopes رئيسية,

الأولى خارج الحلقة و هذا نعرفه ببساطة, و الثانية هي المتغيرات المعرفة في statements الـ for و هذه تعرف بدية تنفيذ الحلقة, و تموت عند الخروج من الحلقة كما في حالة متغيرنا i,

الـ scop الثالث, هو المتغيرت المعرفة داخل الحلقة, حيث تعتبر متغيرات معرفة على مستوى الدورة الواحدة فقط,

أخي Blueteeth,,

اقتباس
-بالنسبة للسؤال فأنا بصراحة معرفش بس ممكن نألف biggrin.gif, ال global variables أكيد مش بتتحجز فى ال stack و بالتالى علشان ندخلها مش عايزين stack pointer و البروسيسور مش حيحسب ال offset اللى حيروح يجيبها منه لكن أعتقد حيبقى مخزن ال direct address بتاع المتغير, علشان كدة ال access لل global أعتقد إنه حيبقى أسرع.

بالفعل لو كان المتغير المحلي معرفاً على الـ stack فسيتم حساب الـ offset الخاص به, و لكنها العملية تتم بسرعة كبيرة جداً داخل المعالج و قد لا يكون هناك فرق حقيقة بين الوصول للمتغيرات سواء كانت عامة أو محلية,

تحياتي ,,

#13

أهلاً Blueteeth ,,

اقتباس
ممم بس أعتقد موضوع وضع المتغيرات فى ال registers دا راجع كليا للكومبايلر, حتى مع كلمة register فأنت لا تضمن أن ال run-time فعلا سيضعه فى ال registers.

يعنى أنا لو بستخدم متغير عام كمتغير للوب (بدل ال i يعنى), هل سيظل بالذاكرة برضه؟

في ++C, المترجمات إجبارياً تقوم بوضع المتغيرات العامة في الذاكرة,

بينما في حالة المتغيرات المحلية, فالوضع الافتراضي (غالباً) أن المترجم سيستغل المسجلات لوضع المتغيرات فيها,

بالطبع إذا كان عدد المتغيرات كبيراً سيضع المترجم ما يستطيع من المتغيرات في المسجلات و يضع الباقي في الذاكرة, و ربما وضع جميع المتغيرات في الذاكرة أيضاً كاحتمال :)

تحياتي ,,

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 27 يناير 2008 في 06:13

#14

السلام عليكم

اقتباس
في ++C المتغيرات العامة تكون في الذاكرة دائماً! أما المتغير i فلن يكون على الـ stack بل سيكون في أحد الـ registers الخاصة بالمعالج

ليس صحيح اخي خالد , المتغير المحلي لا يكون في مسجلات المعالج الا عند وقت تنفيذ عملية معينة عليه , يعني في المثال السابق يتم حجز مكان لـi في المكدس ومن ثم تحميل قيمته في احد المسجلات ثم اضافة 1 الى المسجل ثم حفظ القيمة الجديدة مرة اخرى في المكدس بالمكان المخصص له , كذلك الأمر مع المتغيرات العامة عند اجراء العمليات عليها ( وان كانت محجوزة في الذاكرة) .

اقتباس
لماذا ؟ لأن المترجم عندما يحول الكود إلى (أسمبلي) فإن كل المتغيرات المحجوزه تكون في قسم واحد مع بعضها بغض النظر عن كونها محليه أو (دوليه) أو حتى (إقليمية) , هذا حسب ما أعتقد وهو بالأغلب صحيح

المتغيرات العامة فقط هي التي يتم حجز مساحة من الذاكرة لها ,أما المتغيرات المحلية فلا يتم تخصيص مساحة لها في الذاكرة اصلا بل في المكدس وذلك عند بداية اي روتين او اجراء ,لاحظ هذا الامر عند بداية اي اجراء :

sub esp,xx

أو

add esp,-xx

حيث xx هي مجموع احجام المتغيرات المحلية لهذا الاجراء , وهذا الكلام بغض النظر عن مكان استخدام المتغير المحلي داخل الاجراء.

------------------------------

أما رأيي فمع الأخ خالد فالمتغيرات المحلية اسرع عموما ,السبب :

عند استخدام متغير محلي فهذا يعني استخدام المكدس ولفعل ذلك فإن المترجم يقوم دائما في بداية اي اجراء او دالة بحفظ مؤشر المكدس في احد المسجلات , بعد ذلك يقوم بتحميل قيمة المتغير عند الحاجة عن طريق الازاحة النسبية بينه وبين مؤشر المكدس ,عن طريق الامر mov او lea .

هذه الاوامر تنفذ اسرع عند التعامل مع المسجلات والازاحة النسبية منها عند التعامل مع الoffset الثابتة (انظر الـClock times) .

تم تعديل هذه المشاركة بواسطة GamingMasteR في 27 يناير 2008 في 07:23

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#15

أهلاً GamingMasteR ,,

اقتباس
ليس صحيح اخي خالد , المتغير المحلي لا يكون في مسجلات المعالج الا عند وقت تنفيذ عملية معينة عليه , يعني في المثال السابق يتم حجز مكان لـi في المكدس ومن ثم تحميل قيمته في احد المسجلات ثم اضافة 1 الى المسجل ثم حفظ القيمة الجديدة مرة اخرى في المكدس بالمكان المخصص له , كذلك الأمر مع المتغيرات العامة عند اجراء العمليات عليها ( وان كانت محجوزة في الذاكرة) .

جميل :resentful: , بالنسبة للمتغيرات المحلية, على سبيل المثال, عند استدعاء الدالة, يتم وضع قيم المسجلات على الـ stack لاسترجاعها قبل العودة للمستدعي الأصلي,

بما أننا نملك الآن مسجلات فارغة, لماذا نحتاج لحجز مكان على الـ stack إذا كانت المسجلات فارغة أصلاً ؟

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 27 يناير 2008 في 07:28

#16
اقتباس
بما أننا نملك الآن مسجلات فارغة, لماذا نحتاج لحجز مكان على الـ stack إذا كانت المسجلات فارغة أصلاً ؟

لضمان عدم كتابة دالة فرعية داخل الاجراء الاصلي على المسجلات , ليس هذا فحسب !

المترجمات ليست بهذا الذكاء , فكما قلت على المثال السابق : يتم تخصيص مساحة للرقم i في المكدس, يتم وضع قيمته في مسجل ثم زيادة المسجل بواحد ثم اعادة تخزين القيمة الجديدة في المكدس ثم المقارنة بين قيمة i التي في المكدس بشرط الloop وتتكرر هذه العملية الى انتهاء اللوب .

عملية مرهقة جدا بالرغم من بساطتها وامكانية اجراءها بشكل لا يرهق المعالج بهذا الشكل , لكن كما قلت المترجمات ليست بهذا الذكاء وهو شئ طبيعي فلا يستطيع مطوروها ان يضعو احتمال لكل شئ .

للمعلومة : المتعارف عليه في نظام الوندوز (والذي كتب بالسي) انها تتجنب تغيير مسجلي Esi-Edi فقط لذلك يجب حفظ باقي المسجلات قبل استدعاء API او اجراء فرعي

تم تعديل هذه المشاركة بواسطة GamingMasteR في 27 يناير 2008 في 07:39

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#17
اقتباس
لضمان عدم كتابة دالة فرعية داخل الاجراء الاصلي على المسجلات , ليس هذا فحسب !

أخي العزيز, هل يمكن أن تشرح كيف يمكن أن يتم هذا الشيء, على الرغم من أننا قمنا بحفظ المسجلات لحظة مناداة الدالة ؟

بمعنى أننا لو غيرنا قيم المسجلات داخل الدالة فلن يؤثر هذا بشيء على سير البرنامج الرئيسي لأن قيم المسجلات ستعود كما كانت قبل الدخول للدالة,

بالطبع يستثنى من هذا المسجلات المتعارف عليها في المعالجات و التي تحميل القيمة المعادة من الدوال,

تحياتي ,,

#18

يا جماعة المتغيرات المحلية لا يتم وضعها في الـ stack إلا إذا قامت الدالة بنداء دالة أخرى

يعني ما يحدث عموما هو التالي :

المتغيرات العامة يتم حجز مكان ثابت لها بالذاكرة

ثم تقوم الـ main بحجز ما تريد من الذاكرة لمتغيراتها وعند نداءها لأي دالة تقوم بوضع متغيراتها في الـ stack

وهذه الدالة الأخيرة - فلنسميها x - بدورها إذا أرادت استدعاء دالة أخرى - كأن تكون الدالة iterative - تقوم بوضع متغيراتها في الـ stack وتستدعي الدالة الجديدة

بعد ذلك عندما تنتهي الدالة الجديدة من التنفيذ تعود إلى الدالة التي استدعتها - x - ويتم نقل متغيرات هذه الدالة إلى الذاكرة حتى تنتهي ثم يتم محو متغيراتها ثم تعود للـ main ويتم تحميل متغيرات الـ main من الـ stack إلى الذاكرة

هذا مثال بسيط وهذا هو الذي درسته عند دراستي لأنظمة التشغيل وكيفية التنقل بين البرامج وبالتأكيد فإن التنقل بين البرامج هو نفسه التنقل بين الدوال

أما أن يقول أحد أن المتغيرات المحلية تكون في الـ stack طيلة الوقت حتى أثناء عمل الدالة فهذا غير منطقي لأن الـ stack يتم تنفيذه عن طريق الـ linked list وبالتالي فلا يمكن الوصول للمتغيرات فيه بشكل عشوائي فما الذي سيحدث إذا كان عندنا دالة بها array من ألف خانة وكانت جميعها في الـ stack وأردنا الوصول للخانة 999 :blink: طبعا سنحتاج إلى قراءة الألف خانة حتى نصل إلى الخانة الأخيرة وهذا سيستهلك وقت من المعالج بدون أي داعي لذلك فإن متغيرات أي دالة يتم تحميلها من الـ stack إلى الذاكرة العادية أثناء تنفيذ هذه الدالة

وبالنسبة لموضوع الـ registers فلا يوجد فرق بين متغير محلي أو حتى دولي لأن أي عملية يتم تنفيذها تحتاج إلى نقل المتغيرات إلى registers وهذه المتغيرات ستظل في الـ registers إلى أن نحتاج إلى وضع متغيرات جديدة فيتم محو المتغيرات القديمة من الـ registers وتظل موجودة في الـ cache وهذا سواء كانت محلية أو غير محلية

نأتي إلى حالتنا هذه

في حالة الكود الذي يستخدم متغير محلي فلا يوجد أي داعي لوضع أي شئ في الـ stack لأن الأمر for لن يقوم باستدعاء دالة أخرى حتى يتم وضع i في الـ stack وعندما يتم وضع المتغير i في register من الـ registers الموجودة في المعالج فلا يوجد أي متغير آخر ينافسه على هذا المكان وبالتالي سيظل فيه حتى يقوم الويندوز بالإنتقال إلى برنامج آخر ونفس هذا الأمر سيحدث في المتغير العام فما هو الفارق إذا

ثم أنتم تقولون أن المتغير المحلي سيكون أسرع بينما الذي حدث معي عند التجربة كان العكس :blink: وقد جربت أكثر من مرة

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#19
اقتباس
هذا مثال بسيط وهذا هو الذي درسته عند دراستي لأنظمة التشغيل وكيفية التنقل بين البرامج وبالتأكيد فإن التنقل بين البرامج هو نفسه التنقل بين الدوال

التنقل بين البرامج شئ وبين الدوال شئ أخر , المنقح بيني وبينكم .

اقتباس
فما الذي سيحدث إذا كان عندنا دالة بها array من ألف خانة وكانت جميعها في الـ stack وأردنا الوصول للخانة 999 blink.gif طبعا سنحتاج إلى قراءة الألف خانة حتى نصل إلى الخانة الأخيرة وهذا سيستهلك وقت من المعالج بدون أي داعي لذلك فإن متغيرات أي دالة يتم تحميلها من الـ stack إلى الذاكرة العادية أثناء تنفيذ هذه الدالة

من قال هذا ؟؟؟؟؟؟؟؟؟ لماذا يوجد شئ اسمه الـRelative Address اذا ؟؟

اقتباس
في حالة الكود الذي يستخدم متغير محلي فلا يوجد أي داعي لوضع أي شئ في الـ stack لأن الأمر for لن يقوم باستدعاء دالة أخرى حتى يتم وضع i في الـ stack وعندما يتم وضع المتغير i في register من الـ registers الموجودة في المعالج فلا يوجد أي متغير آخر ينافسه على هذا المكان وبالتالي سيظل فيه حتى يقوم الويندوز بالإنتقال إلى برنامج آخر ونفس هذا الأمر سيحدث في المتغير العام فما هو الفارق إذا

نتحدث عن داخل البرنامج الواحد وليس عملية تنظيم الكرنيل للبرامج المختلفة ... وإلا دخلنا في متاهات .

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#20

السلام عليكم ,,

اقتباس
التنقل بين البرامج شئ وبين الدوال شئ أخر , المنقح بيني وبينكم .

صحيح, و الفرق ربما أنه في الأولى سيتم حفظ قيم أخرى غير قيم المسجلات عند التنقل بين البرامج,

عموماً يمكن اعتبار التنقل بين البرامج على أنه تنقل بين معالجات وهمية كل معالج لح حالته الخاصة,

أما في حالة التنقل بين الدوال فالمهم هو حفظ المسجلات ليصبح عمل الدوال مخفي و أكثر سلاسة,

و لكن حقيقة إذا قلنا بكلامك أخي GamingMasteR,

اقتباس
بما أننا نملك الآن مسجلات فارغة, لماذا نحتاج لحجز مكان على الـ stack إذا كانت المسجلات فارغة أصلاً ؟

تحياتي ,,

#21
اقتباس
من قال هذا ؟؟؟؟؟؟؟؟؟ لماذا يوجد شئ اسمه الـRelative Address اذا ؟؟

ما دخل الـ Relative Address بالـ stack الـ stack عبارة عن linked list

اقتباس
نتحدث عن داخل البرنامج الواحد وليس عملية تنظيم الكرنيل للبرامج المختلفة ... وإلا دخلنا في متاهات .

لا يوجد مشكلة

في حالة الكود الذي يستخدم متغير محلي فلا يوجد أي داعي لوضع أي شئ في الـ stack لأن الأمر for لن يقوم باستدعاء دالة أخرى حتى يتم وضع i في الـ stack وعندما يتم وضع المتغير i في register من الـ registers الموجودة في المعالج فلا يوجد أي متغير آخر ينافسه على هذا المكان وبالتالي سيظل فيه ونفس هذا الأمر سيحدث في المتغير العام فما هو الفارق إذا

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#22

اقتباس من wiki :

اقتباس
Functions of the call stack:

Local data storage – A subroutine frequently needs memory space for storing the values of local variables, the variables that are known only within the active subroutine and do not retain values after it returns. It is often convenient to allocate space for this use by simply moving the top of the stack by enough to provide the space. This is very fast to do compared with, say, a heap allocation. Note that each separate activation of a subroutine gets its own separate space in the stack for locals

.

اقتباس أخر :

اقتباس
Local variables are special because in most languages they are automatic variables stored on the call stack directly.

أظن سنتفق ولسنا بحاجة الى الكلام عن الـlocal & global storage مرة اخرى :happy:

اقتباس
في حالة الكود الذي يستخدم متغير محلي فلا يوجد أي داعي لوضع أي شئ في الـ stack لأن الأمر for لن يقوم باستدعاء دالة أخرى حتى يتم وضع i في الـ stack وعندما يتم وضع المتغير i في register من الـ registers الموجودة في المعالج فلا يوجد أي متغير آخر ينافسه على هذا المكان وبالتالي سيظل فيه ونفس هذا الأمر سيحدث في المتغير العام فما هو الفارق إذا

كما قلت سابقا : المترجمات ليست بذلك الذكاء - تتكلمون عنها وكأنها شخص يجلس بجانبك ويعرف ماذا تريد بالضبط , انما هي قوالب تضعها في المكان المناسب بالشكل المناسب .

اخي باسم : هل لديك منقح ؟؟؟ اريدك ان ترى الكود بنفسك كي يتضح لك الامر .

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#23

أنا فصلت وهنجت والكلام كله دخل في بعضه

يعني أيهما أسرع الآن

تم تعديل هذه المشاركة بواسطة باسم الموجي في 27 يناير 2008 في 08:50

من أقوال الأئمة

الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".

الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".

الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".

الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".

علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".

وكل خير في اتباع من سلف وكل شر في ابتداع من خلف

#24
اقتباس
أنا فصلت وهنجت

وانا عايز انام :lol:

ولسة خالد شكله فايق ومش ناوي يخليني انام النهاردة <_<

اقتباس
يعني أيهما أسرع الآن

المحلي والسبب الـclocks وليس شئ اخر

mov eax, dword ptr ds:[0xffdf0308]

jmp dword ptr [eax+0xfc]

#25

إيه يا شباب لسه الليل في أوله عندي :D

على العموم أنا راح أكمل الموضوع معاكم بكرة, لأني ناوي أركب مترجم و منقح و أجهز العدة على جهاز صاحبي :D بينما أصلح جهازي,

سلام,,

هذا الموضوع مغلق.

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…