السلام عليكم ورحمة الله وبركاته
كثيراً ما نسمع في الأسمبلي أن عملية الضرب mul بطيئة ..
سنناقش اليوم بإذن الله صحة هذا القول ..
سنقارن أولا الضرب ب4 والذي يقابل الإزاحة المنطقية للعدد ب2 لليسار
في الكود التالي قمت بمقارنة الوقت اللزم للقيام بمليار عملية ضرب ومليار عملية إزاحة منطقية لليسار
(توجد بعض التعليمات للتحكم أيضاً .. (الكود على Visual C++8 )
لنبدأ :
#include<stdio.h>
#include<windows.h>
int main()
{
int a=GetTickCount();
_asm{
mov ecx,1000000000
go:
mov eax,15
mov ebx,4
mul ebx//تعليمة الضرب
loop go
}
int b=GetTickCount();
_asm{
mov ecx,1000000000
go2:
mov eax,15
mov ebx,4
shl eax,2//تعليمة الإزاحة
loop go2
}
int c=GetTickCount();
printf("mul=%i\nshl=%i\n",b-a,c-b);
return 0;
}شغّل البرنامج واكتشف الفرق :)الإزاحة أسرع من الضرب بحوالي 1622 ميللي ثانية .. في مليار عملية أي من أجل عملية واحدة 0.000001622 ميللي ثانية .. هو الفرق بين السرعتين !!
والآن لنجرّب الضرب بــ 5 ..
نحتاج للضرب ب5 إلى الضرب ب4 ثم إضافة العدد .. مثلا 8*5 هي 8*4+8
ولنقارن سرعة الضرب مع سرعة الإزاحة والجمع ( اثنان ضد واحد ! من الأسرع ؟)
#include<stdio.h>
#include<windows.h>
int main()
{
int a=GetTickCount();
_asm{
mov ecx,1000000000
go:
mov eax,15
mov ebx,5
mul ebx//تعليمة الضرب
loop go
}
int b=GetTickCount();
_asm{
mov ecx,1000000000
go2:
mov eax,15
mov ebx,5
shl eax,2//تعليمة الإزاحة
add eax,ebx
loop go2
}
int c=GetTickCount();
printf("mul=%i\nshl=%i\n",b-a,c-b);
return 0;
}تخيّل أن الجمع والإزاحة معاً .. أسرع من الضرب ! تقريبا الفرق 1435 ميللي ثانية !هل هذا يعني أن أي عملية ضرب يمكننا تحويلها إلى إزاحة ثم جمع .. وسنصل إلى كود أسرع ؟
أترك لكم الإجابة ..
والله ولي التوفيق
باستخدام الطريقة
.