الساعة الان 8 صباحا ومواصلين من امس لم ننام
لا تنسى : IDA-OllyDbg افضل الموجودين , وكله يؤدي الغرض
mov eax, dword ptr ds:[0xffdf0308]
jmp dword ptr [eax+0xfc]
الساعة الان 8 صباحا ومواصلين من امس لم ننام
لا تنسى : IDA-OllyDbg افضل الموجودين , وكله يؤدي الغرض
mov eax, dword ptr ds:[0xffdf0308]
jmp dword ptr [eax+0xfc]
اقتباسالمحلي والسبب الـclocks وليس شئ اخر
جرررررررررررررررررررررررررررررررررررررررررر
أنا جربت عندي وكان الـ global أسرع يعني أصدقك الآن أم أصدق الـ VC++
من أقوال الأئمة
الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".
الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".
الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".
الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".
علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".
وكل خير في اتباع من سلف وكل شر في ابتداع من خلف
#include <windows.h>
#include <iostream.h>
unsigned int i;
int main(int argc, char* argv[])
{
int x = GetTickCount();
for( i = 0; i < 1000000000; i++ );
int y = GetTickCount();
cout << (y-x);
cin >> i;
return 0;
}اعمل 2 مرة local ومرة global :
اختار الملفين مع بعض ودوس enter وشوف مين قيمته اعلى يبقى الابطئ
وزود الرقم لو عايز تلحظ فرق اكبر
mov eax, dword ptr ds:[0xffdf0308]
jmp dword ptr [eax+0xfc]
هذه الطريقة لا تصلح لأن أحدهما سيكون في المقدمة وسيأخذ مساحة أكبر من المعالج والآخر سيكون في الخلف وسيأخذ مساحة أقل
تم تعديل هذه المشاركة بواسطة باسم الموجي في 27 يناير 2008 في 10:46
من أقوال الأئمة
الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".
الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".
الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".
الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".
علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".
وكل خير في اتباع من سلف وكل شر في ابتداع من خلف
غرييييييييييييبة لأن عندي بيقول العكس :blink: !
mov eax, dword ptr ds:[0xffdf0308]
jmp dword ptr [eax+0xfc]
كي لا تقوم بقتلي شوف رابط الفيديو :lol:
mov eax, dword ptr ds:[0xffdf0308]
jmp dword ptr [eax+0xfc]
السلام عليكم ...
اقتباسغرييييييييييييبة لأن عندي بيقول العكس
هذه العملية قد تختلف من جهاز الي اخر وذلك بسبب كمية البرامج المفتوحة واسباب اخري، حتي القيمة قد تختلف من معالج الي اخر.
+=+
سرعة الـloop لن تتاثر بنوع المتغير وذلك بسبب ان المعالج عند اللوب (في وضع المتغير العام او الخاص)
يجلب القيمة مرة واحدة فقط من (الاستاك من الزاكرة الافتراضية من اي مكان ،لايهم ذلك) الي احدي المسجلات
ويجري عملية الـLoop بطريقة عادية مع عمل مقارنة وتذايد(Increment) للقيمة التي في ذلك المسجل بالقيمة النهائية للـFor Loop
( _ /)
(='.'=)
(")-(")
GamingMasteR كتب:غرييييييييييييبة لأن عندي بيقول العكس :blink: !
عندما تقوم بتشغيل الملفين فإن أحدهما يكون في المقدمة (Focus) والآخر في الخلف (NoFocus) وهذا يؤثر جدا على النتيجة لذلك قلت لك أن هذه الطريقة غير صحيحة
أنا على العموم قمت بتجربة أخرى
كتبت هذا الكود في VB
Private Sub Form_Load()
Shell ("c:\Local.exe"), vbNormalNoFocus
Shell ("c:\Global.exe"), vbNormalNoFocus
End Subطبعا حتى أضمن أن الملفين لا يوجد عليهما Focus بحيث يتم التعامل معهما بنفس الطريقة وكانت النتيجة أن Local أسرع حتى بعد أن عدلت الكود إلى التالي
Private Sub Form_Load()
Shell ("c:\Global.exe"), vbNormalNoFocus
Shell ("c:\Local.exe"), vbNormalNoFocus
End Subأيضا كانت Local أسرع
:(
من أقوال الأئمة
الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".
الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".
الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".
الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".
علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".
وكل خير في اتباع من سلف وكل شر في ابتداع من خلف
السلام عليكم ,,
عدنا و لله الحمد من جديد,
في البداية, من شروط لغة ++C, أن يكون التعامل مع المتغيرات العامة في الذاكرة مباشرة, و لا يسمح باستخدام مسجلات المعالج,
أما بالنسبة للمتغيرات المحلية, فالمعالج في الوضع الافتراضي يحاول أن تكون مسجلات المعالج تمثل تلك المتغيرات, إلا إن لم يستطع لسبب من الأسباب العديدة.
فلو طرحنا السؤال المذكور في بداية الموضوع من جديد, مع الاطلاع على كود الـ Assembly الذي تكون, يمكننا فهم الموضوع بطريقة أفضل.
الحالة الأولى هي عندما يكون المتغير محلياً :
لاحظ الآن كود الـ Assembly الناتج :
لو نظرت إلى ما بعد الـ for loop مباشرة, ستجد أن المترجم قام بعملية الـ initialization للصفر بالنسبة للمسجل esi و وهو في الحقيقة يمثل المتغير i B)
قبل عملية المقارنة, المترجم أضاف واحد للمسجل نفسه, المترجم لم يحجز أي مكان في الذاكرة للمتغير i, بل استخدم المسجلات مباشرة.
في الحالة الثانية, عندما يكون المتغير عاماً :
لاحظ الكود الناتج :
المترجم قام بحجز مكان للمتغير i على العنوان 0x403374, ثم أصبح يتناقله بين المسجل eax و مكانه في الذاكرة,
أي أن المتغير فعلياً في الذاكرة, و عندما يريد المترجم زيادة المتغير فإنه ينقله للمسجل, ثم يعيده مرة أخرى,
حسناً هناك معالجات لا يحتاج فيها المترجم لنقل قيمة في الذاكرة إلى مسجل لزيادتها, هذا كمثال في معالجات موتورولا -_- :
ADDQ.L #1, i
هناك معالجات تقبل التعامل مع الذاكرة مباشرة في كثير من العمليات, يمكنك الرجوع للفروق بين معمارية CISC و معمارية RISC لتعرف ما هي المعماريات الرئيسية في عالم المعالجات.
و لكن باختصار, المتغير i عندما يكون عاماً, فإن قيمته يجب أن تكون في الذاكرة و محدثة دائماً, سواء استخدمنا مسجل مؤقت خلال كل دورة أم لم نستخدمه على حسب بنية المعالج.
أحد الأسباب التي التي أعتقد أنها صحيحة, هي انطلاق interrupt على سبيل المثال خلال تنفيذ التكرار, و كان هذا الـ interrupt يتعامل مع المتغير العام i,
أخيراً, الكود السابق تم ترجمته على vc2008 express, و استعملت المنقح الخاص به,
تحياتي ,,
تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 27 يناير 2008 في 19:37 — السبب: أخطاء إملائية
السلام عليكم,
ولله أنا مستمتع بالنقاش جدااااااااا :)
بس ليا ملاحظة صغيرة على كلام الأخ باسم لأن أعتقد إن عنده لبس صغير, ال stack منفذة عن طريق ال linked list فى ال software اللى إحنا بنعمله علشان نعمل simulation لل stack الحقيقية, لكن على الهاردوير يوجد stack حقيقية فعلا فى الذاكرة و المعالج مش محدد بأخر عنصر فيها بس لكن ممكن يحسب offset علشان يدخل أى عنصر جواها.
والله أعلم.
*أخى خالد, هل تعرف طريقة لمشاهدة الأسمبلى فى ال gcc ؟
تعليقا على كلام الأخ Blueteeth
أولا هذا رابط الويكي عن الـ stack
وأقتبس منه هذه العبارة
اقتباسthe contents of the stack are hidden. Only the top plate is visible, so to see what is on the third plate, the first and second plates will have to be removed.
والآن كيف توضع المتغيرات المحلية في الـ stack ونحن نحتاج إلى الوصول إليها بشكل عشوائي فأنا ما زلت غير قادر على فهم هذه الجزئية
من أقوال الأئمة
الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".
الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".
الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".
الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".
علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".
وكل خير في اتباع من سلف وكل شر في ابتداع من خلف
اقتباسسرعة الـloop لن تتاثر بنوع المتغير وذلك بسبب ان المعالج عند اللوب (في وضع المتغير العام او الخاص)يجلب القيمة مرة واحدة فقط من (الاستاك من الزاكرة الافتراضية من اي مكان ،لايهم ذلك) الي احدي المسجلات
ويجري عملية الـLoop بطريقة عادية مع عمل مقارنة وتذايد(Increment) للقيمة التي في ذلك المسجل بالقيمة النهائية للـFor Loop
ليس صحيح - يتم حفظ المتغير سواء المحلي او العام بعد اي تغيير يطرأ عليه, راجع ردودي السابقة .
اقتباسعندما تقوم بتشغيل الملفين فإن أحدهما يكون في المقدمة (Focus) والآخر في الخلف (NoFocus) وهذا يؤثر جدا على النتيجة لذلك قلت لك أن هذه الطريقة غير صحيحة
لو لاحظت الفيديو ستجد اني اعطيت الـFocus للـglobal ومع ذلك الـlocal كان اسرع .
اقتباسأيضا كانت Local أسرع
غلطة دي ولا المحلي كان اسرع من الأول وانت متلخبط ؟؟؟؟؟؟؟ :lol:
اقتباسلو نظرت إلى ما بعد الـ for loop مباشرة, ستجد أن المترجم قام بعملية الـ initialization للصفر بالنسبة للمسجل esi و وهو في الحقيقة يمثل المتغير i
اغلق خواص الـoptimizations وشوف مرة تانية .
mov eax, dword ptr ds:[0xffdf0308]
jmp dword ptr [eax+0xfc]
مداخلة صغيرة
أعتقد انة يجب الاشارة فى معرض الحديث لدور الCache Memory فالمثال المعطى مثلا أعطى عندى أن المحلى أسرع بالضعف
و كان من الممكن أن تكون النسبة أسوأ بكثير لولا دور الكاش الذى أدى الى تسريع الولوج الى و تعديل المتغير العام كثير الاستعمال
هذا اعتقادى الشخصى
و شكرا
السلام عليكم ,,
أخي BlueTeeth ,,
اقتباس*أخى خالد, هل تعرف طريقة لمشاهدة الأسمبلى فى ال gcc ؟
قبل استخدام vc2008 express كنت أستخدم code blocks و هو يحتوي على disassembler يمكن استخدامه من الـ IDE مباشرة,
و لكن نصيحة مني ألقي نظرة على vc2008 express لأنه أكثر من رائع و لا أعتقد أن هناك عودة لـ gcc :lol:
لم أكن أعرف أن مايكروسوفت تمتلك برامج بمثل هذه الروعة :ph34r:
أخيراً وصلتلك يا GamingMasteR :evil:
اقتباساغلق خواص الـoptimizations وشوف مرة تانية .
أنا ترجمت الكود على الإعدادات الافتراضية لـ vc2008 express و لا يوجد اصلاً سوى عدة خيارات غير مفصلة لعمل Optimization, و لكني لم استخدم أي واحد منها لأرى تصرف المترجمات الافتراضي في السؤال المطروح :P
إضافة إلى ذلك, كان ذلك أول درس اسمبلي لي في عالم الـ x86 :D
أخ ASDen ,,
اقتباسمداخلة صغيرةأعتقد انة يجب الاشارة فى معرض الحديث لدور الCache Memory فالمثال المعطى مثلا أعطى عندى أن المحلى أسرع بالضعف
و كان من الممكن أن تكون النسبة أسوأ بكثير لولا دور الكاش الذى أدى الى تسريع الولوج الى و تعديل المتغير العام كثير الاستعمال
الصراحة أذكر أني قرأت أيضاً أن المتغيرات العامة لا تخزن في cache المعالج :rolleyes:
و لكن لست متأكداً من هذه النقطة, و لا أدري إن كنت قد فهمت الموضوع بشكل صحيح أم لا,
أنا في انتظار من يفيدنا في هذه النقطة,
تحياتي ,,
اقتباسو لكن لست متأكداً من هذه النقطة, و لا أدري إن كنت قد فهمت الموضوع بشكل صحيح أم لا,
المفروض ان الكاش مستواها هاردوير فقط للتسريع فكيف يتم هذا المنع ؟ أو بمعنى أصح كيف يفرق الهاردوير
الأخ الفاضل ...
بإستخدام VC++ 6.0
الحالة الوحيدة التى كان فيها Global اسرع من Local عندما اسخدمت المؤشرات Pointers، واستخدمت النوع register مع Global فى الدالتين (local2 - global2)، ولكن الأداء بوجهاً عام أبطأ فى Pointers.
الدالتين (SetThreadPriority - SetPriorityClass)، لجعل البرنامج يعمل فى Critical Real Time دون التأثر بأى برامج أخرى (لاحظ ان الكمبيوتر سيتجمد اثناء عمل البرنامج).
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#define LOOPS 200000000
unsigned long g_var;
long global0() // Normal
{
unsigned long ticks = GetTickCount();
for(g_var = 0; g_var < LOOPS; g_var++);
return GetTickCount() - ticks;
}
long local0()
{
unsigned long l_var;
unsigned long ticks = GetTickCount();
for(l_var = 0; l_var < LOOPS; l_var++);
return GetTickCount() - ticks;
}
// /////////////////////////////
long global1() // Static
{
unsigned long ticks = GetTickCount();
for(g_var = 0; g_var < LOOPS; g_var++);
return GetTickCount() - ticks;
}
long local1()
{
static unsigned long l_var;
unsigned long ticks = GetTickCount();
for(l_var = 0; l_var < LOOPS; l_var++);
return GetTickCount() - ticks;
}
// /////////////////////////////
long global2() // Register
{
register unsigned long* pg_var = &g_var;
unsigned long ticks = GetTickCount();
for(*pg_var = 0; *pg_var < LOOPS; (*pg_var)++);
return GetTickCount() - ticks;
}
long local2()
{
unsigned long l_var;
unsigned long* pl_var = &l_var;
unsigned long ticks = GetTickCount();
for(*pl_var = 0; *pl_var < LOOPS; (*pl_var)++);
return GetTickCount() - ticks;
}
// /////////////////////////////
int main(int argc, char* argv[])
{
SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
unsigned long g_ticks0 = global0();
unsigned long l_ticks0 = local0();
unsigned long g_ticks1 = global1();
unsigned long l_ticks1 = local1();
unsigned long g_ticks2 = global2();
unsigned long l_ticks2 = local2();
TCHAR tBuffer[129];
sprintf(tBuffer, TEXT("\r\nNormal\r\nGlobal0: %u\r\nLocal0: %u\r\n"), g_ticks0, l_ticks0);
printf(TEXT("%s"), tBuffer);
OutputDebugString(tBuffer);
sprintf(tBuffer, TEXT("\r\nStatic\r\nGlobal1: %u\r\nLocal1: %u\r\n"), g_ticks1, l_ticks1);
printf(TEXT("%s"), tBuffer);
OutputDebugString(tBuffer);
sprintf(tBuffer, TEXT("\r\nRegister\r\nGlobal2: %u\r\nLocal2: %u\r\n"), g_ticks2, l_ticks2);
printf(TEXT("%s"), tBuffer);
OutputDebugString(tBuffer);
printf(TEXT("\r\npress ENTER to exit..."));
getchar();
return 0;
}شكراً
Nothing is impossible, the word impossible itself says that: I M - Possible
لي ملاحظه أو أستفسار للأخوه
لا أعتقد أن القياس العملي لهذه التجربه هو حل لمعرفة أيهم أسرع , ذلك بسبب إختلاف الظروف في النظام في العتاد وفي كثير من الأشياء هذا على حسب علمي
أنا أتحدث من منطق تجريدي (يعني مفهومي) وليس من منطق عملي , يعني ممكن عمليا تطلع نتائج معينه , ولكن
ولكن حسب وجهة نظري لا يمكن أن يبت بهذه القضية إلا مفاهيم المترجمات و نظم التشغيل ونظرياتها.
تحياتي وشكرا للجميع على الكم الهائل من المعلومات التي حصلت عليها ...
أخي خالد هذا اقتباس من الكود بدون عمل Optimization في الحالتين :
.text:00401046 Loop: .text:00401046 mov eax, Global_Var .text:0040104B add eax, 1 .text:0040104E mov Global_Var, eax .text:00401053 cmp Global_Var, 0B2D05E00h .text:0040105D jnb short Out_of_Loop .text:0040105F jmp short Loop
.text:00401043 Loop: .text:00401043 mov eax, [ebp+Local_Var] .text:00401046 add eax, 1 .text:00401049 mov [ebp+Local_Var], eax .text:0040104C cmp [ebp+Local_Var], 0B2D05E00h .text:00401053 jnb short Out_of_Loop .text:00401055 jmp short Loop
mov eax, dword ptr ds:[0xffdf0308]
jmp dword ptr [eax+0xfc]
أظن الموضوع ممكن أن يكون معتمد على المترجم نفسه وكل مترجم له أسلوبه وفي كل الأحوال فإن المتغيرات كلها ستوضع في الـ Cache وستتساوى في السرعة بسبب ذلك
من أقوال الأئمة
الإمام علي بن أبي طالب -رضي الله عنه-: "الناس ثلاثة : فعالم رباني ، ومتعلم على سبيل النجاة ، وهمج رِعاع غوغاء أتباع كل ناعق ، يميلون مع كل ريح ، لم يستضيئوا بنور العلم ، ولم يلجئوا إلى ركن وثيق".
الإمام مالك -رحمه الله- : " لن يصلح آخر هذه الأمة إلا بما أصلح به أولها ".
الإمام الأوزاعي -رحمه الله- : " عليك بآثار من سلف وإن رفضك الناس وإياك وآراء الرجال وإن زخرفوه لك بالقول ".
الإمام الفضيل بن عياض -رحمه الله- : " عليك بطرق الهدى و لا يضرك قلة السالكين و إياك و طرق الضلالة ولا يغرك كثرة الهالكين ".
علامة الزمان الإمام الألباني -رحمه الله- : " إن الخلاص إلى أيدي هؤلاء الشباب يتمثل في أمرين لا ثالث لهما ؛ التصفية والتربية ".
وكل خير في اتباع من سلف وكل شر في ابتداع من خلف
و توتة توتة خلصت الحدّوتة !
:lol: :lol: :lol:
mov eax, dword ptr ds:[0xffdf0308]
jmp dword ptr [eax+0xfc]
السلام عليكم ,,
أخي أسامة, دائماً تأتي بالمفيد و الجديد,
الحقيقة أنك اختصرت علينا تجربة الاحتمالات الباقية تقريبأً,
و التي أثارت إنتباهي هي عندما جعلنا المتغير المحلي static :
long global1() // Static
{
unsigned long ticks = GetTickCount();
for(g_var = 0; g_var < LOOPS; g_var++);
return GetTickCount() - ticks;
}
long local1(){
static unsigned long l_var;
unsigned long ticks = GetTickCount();
for(l_var = 0; l_var < LOOPS; l_var++);
return GetTickCount() - ticks;
}فأصبح في الذاكرة إجبارياً و لم يعد هناك فرق بينه و بين المتغير العام :)
إضافة إلى أنني سأستخدم الكود الذي وضعته لكي يعمل البرنامج في windows دون أن يقاطعه شيء آخر في تجاربي,
شكراً على مشاركتك القيمة,
بالنسب لأخي GamingMasteR :rolleyes:
حسناً إذا أغلقنا جميع الـ Optimizations فلا تتوقع الكثير من المترجمات, لأن الـ Optimizer هو أحد أهم الأجزاء التي يتكون منها أي مترجم :wacko:
كما قلت لي سابقاً, كتابة الكود يدوياً سيعطينا نتيجة أفضل من أي مترجم :D
و لكن الكلام هنا عن تصرف مترجمات ++C في الوضع الطبيعي, هناك إرشادات يجب على المترجمات اتباعها و ذلك لإنتاج أكواد أفضل و في هذه النقطة على سبيل المثال تتفق معظم المترجمات حتى مترجمات اللغات الشبيهة بلغة ++C/C على ما أعتقد !,
بالمناسبة ماهو المترجم الذي تستعمله ؟
تحياتي ,,
هذا الموضوع مغلق.
المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية
جارٍ التحقق من المتواجدين…