سؤال

الذي يجمع أسرع كود:"الجواب = n * 3" أو "الجواب = ن+(ن*2)"?

على افتراض أن n هو إما الباحث أو طويل, و هو يعمل على الحديث Win32 إنتل مربع.

هذا من شأنه أن تكون مختلفة إذا كان هناك بعض dereferencing المعنية ، أي أن هذه ستكون أسرع ؟

long    a;
long    *pn;
long     ans;

...
*pn = some_number;
ans = *pn * 3;

أو

ans = *pn+(*pn*2);

أو هو شيء واحد لا داعي للقلق حول تحسين المجمعين ومن المرجح أن يحدث هذا في أي حال من الأحوال ؟

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

المحلول

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

نصائح أخرى

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

MUL EAX,3

ينفذ أسرع من

MOV EBX,EAX
SHL EAX,1
ADD EAX,EBX

آخر المعالج حيث أن هذا النوع من التحسين قد يكون من المفيد ربما كان 486.(نعم, هذا هو منحاز إلى معالجات إنتل ، ولكن ربما ممثل أبنية أخرى أيضا).

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

كما أنه من السهل قياس نفسك, لماذا لا تفعل ذلك ؟ (باستخدام gcc و time من cygwin)

/* test1.c */
int main()
{
    int result = 0;
    int times = 1000000000;
    while (--times)
        result = result * 3;
    return result;
}

machine:~$ gcc -O2 test1.c -o test1
machine:~$ time ./test1.exe

real    0m0.673s
user    0m0.608s
sys     0m0.000s

هل اختبار عدة مرات وكرر عن الحالة الأخرى.

إذا كنت ترغب في إلقاء نظرة خاطفة على الجمعية رمز ، gcc -S -O2 test1.c

هذا يعتمد على المترجم ، التكوين المحيطة رمز.

يجب أن لا محاولة لتخمين ما إذا كانت الأمور 'أسرع دون أخذ القياسات.

في العام يجب أن لا تقلق حول هذا النوع من النانو الأمثل الأشياء في الوقت الحاضر - هو دائما تقريبا كاملة الاعتداد ، إذا كنت حقا العمل في المجال حيث يهم ، سوف يكون بالفعل باستخدام التعريف و تبحث في لغة التجميع الناتج من المحول البرمجي.

ليس من الصعب معرفة ما المحول البرمجي مع رمز (أنا باستخدام DevStudio 2005 هنا).كتابة برنامج بسيط مع التعليمات البرمجية التالية:

int i = 45, j, k;
j = i * 3;
k = i + (i * 2);

ضع نقطة توقف على خط المنتصف ثم قم بتشغيل التعليمات البرمجية باستخدام المصحح.عندما توقف تشغيل, انقر بزر الماوس الأيمن على الملف المصدر وحدد "الذهاب إلى التفكيك".سيكون لديك الآن نافذة مع رمز وحدة المعالجة المركزية المنفذة.ستلاحظ في هذه الحالة أن آخر سطرين تنتج بالضبط نفس التعليمات ، وهي "lea eax,[ebx+ebx*2]" (لا بت وتحويل وإضافة في هذه الحالة بالذات).في حديث IA32 وحدة المعالجة المركزية ، ربما أكثر كفاءة للقيام مول مباشرة بدلا من بت التحول بسبب pipelineing طبيعة وحدة المعالجة المركزية التي تتحمل عقوبة عند استخدام القيمة المعدلة في وقت قريب جدا.

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

أنها لا تعتمد على المترجم كنت فعلا تستخدم ، ولكن من المحتمل جدا أنها تترجم إلى نفس القانون.

يمكنك التحقق من ذلك بنفسك عن طريق إنشاء برنامج الاختبار و التحقق من التفكيك.

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

لا يهتم.أعتقد أن هناك أشياء أكثر أهمية تحسين.كم من الوقت كنت قد استثمرت في التفكير و الكتابة على هذا السؤال بدلا من الترميز والاختبار من قبل نفسك ؟

:-)

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

يمكنك طرح هذا السؤال يشير إلى أن تحسين مترجم يعرف أكثر عن الأمثل مما تفعله.لذا ثق المترجم.استخدام n * 3.

إلقاء نظرة على هذا الجواب وكذلك.

المجمعين جيدة في تحسين رمز مثل لك.أي حديث المترجم سوف تنتج نفس رمز لكل الحالات بالإضافة إلى استبدال * 2 بواسطة shift الأيسر.

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

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