C++普通线性查找与使用汇编优化的时间对比

通过编写简单的for循环线性查找某一个元素,计算出前后的时间差,然后写一个同样功能的汇编版本,计算出时间差,我们看看两者在执行一百万次所执行的时间差

头文件:

extern "C" {
	bool AsmFindArray(long n, long array[], long count);
	bool FindArray(long n, long array[], long count);
}

我们使用extern C,让编译器按照C语言的规则编译产生目标函数。

入口函数:

// main.cpp - Testing FindArray and AsmFindArray

#include <iostream>
#include <time.h>
#include "findarr.h"

using namespace std;

int main(){
	// Fill an array with pseudorandom integers.
	const unsigned ARRAY_SIZE = 10000;
	const unsigned LOOP_SIZE = 1000000;

	long array[ARRAY_SIZE];
	for(unsigned i = 0; i < ARRAY_SIZE; i++)
		array[i] = rand();

	long searchVal;
	time_t startTime, endTime;
	cout << "Enter a value to find: ";
	cin >> searchVal;
	cout << "Please wait. This will take between 10 and 30 seconds...\n";

	// Test the C++ function
	time(&startTime);
	bool found = false;

	for (int n = 0; n < LOOP_SIZE; n++)
		found = FindArray(searchVal,array,ARRAY_SIZE);
	time(&endTime);
	cout << "Elapsed CPP time: " << long(endTime - startTime)
		 << " seconds. Found = " << found << endl;

	// Test the Assembly language procedure:
	time(&startTime);
	found = false;

	for(n = 0; n < LOOP_SIZE; n++)
		found = AsmFindArray(searchVal, array,ARRAY_SIZE);
	time(&endTime);
	cout << "Elapsed ASM time: " << long(endTime - startTime)
		 << " seconds. Found = " << found << endl;

	return 0;
}

FindArray的C++实现函数:

#include "findarr.h"
bool FindArray(long n, long array[], long count)
{
    long *p = array;
    for (int i = 0; i < count; i++,p++)
        if (n == *p)
            return true;
    return false;
}

AsmFindArray的实现函数:

TITLE AsmFindArray Procedure (AsmFindArray.asm)

.586
.model flat,C

AsmFindArray PROTO,
             srchVal:DWORD, arrayPtr:PTR DWORD, count:DWORD

.code
;----------------------------------------------------------------------
AsmFindArray PROC USES edi,
             srchVal:DWORD, arrayPtr:PTR DWORD, count:DWORD
;
; Performs a linear search for a 32-bit integer
; in an array of integers. Returns a boolean
; value in AL indicating if the integer was found.
;----------------------------------------------------------------------
    true = 1
    false = 0

    mov eax,srchVal             ; search value
    mov ecx,count               ; number of items
    mov edi,arrayPtr            ; pointer to array

    repne scasd                 ; do the search
    jz returnTrue               ; ZF = 1 if ound.

returnFalse:
    mov al,false
    jmp short exit

returnTrue:
    mov al,true

exit:
    ret
AsmFindArray ENDP
END

注意,C++链接汇编文件,在32位模式下必须指定Model为:.model flat,C. 在这里,我们使用了repne scasd命令替代循环的loop指令优化代码。编译器编译C++的FindArray函数默认是使用loop的。

我们使用ml /c 指令编译FindArray.cpp 产生FindArray.obj ,使用ml /c /coff AsmFindArray.asm 生成AsmFindArray.obj文件

然后用link main.obj FindArray.obj AsmFindArray.obj文件生成最后的main.exe

最后,我们看看结果的输出:


我们可以看出结果的差别还是很大的,这说明在某些特殊的场合,我们可以利用repne repe scasd scasb scasw等这些指令优化传统的for循环。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值