Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: FirstBit() in assembler

Author: Koundinya Veluri

Date: 03:26:10 01/15/02

Go up one level in this thread


On January 14, 2002 at 11:27:00, Severi Salminen wrote:

>
>>I'm using this for LastBit() for a8 = 0, b8 = 1, h1 = 63 orientation:
>>
>>	bsr		eax, [bb + 4]
>>	jz		L10
>>	add		eax, 32
>>	jmp		L11
>>L10:
>>	bsr		eax, [bb]
>>L11:
>>
>>This should work, but I'm relatively new to assembly and I wonder if this can
>>get any better...?
>
>Well, you could remove the other jmp and add one "sub eax,32". It would have
>less branches but not sure if it was faster. Try it:
>
>bsr eax,bb+4
>jnz exit
>bsr eax,bb
>sub eax,32
>exit:
>add eax,32
>
>...or something. Your orientation makes my head spin so double check the above.

Interesting idea, but the first one seems to be noticably (38%) faster on my
computer. I guess an unconditional jump is faster than an extra sub instruction.
There's something else strange that didn't work as I expected. I tried the
FirstBit() with the bsr/add/bsr method and another method with a conditional
jump (which does not make the assumption that zero means register is unchanged),
and the one with the conditional jump was much faster. Here's the code I used to
test it and the output I get after that. Is there something wrong with this?

#include <iostream>
using namespace std;

#include <windows.h>

#define ITERATIONS		(1000000000)

inline const int FirstBit1(const unsigned __int64 bb);
inline const int FirstBit2(const unsigned __int64 bb);
inline const int LastBit1(const unsigned __int64 bb);
inline const int LastBit2(const unsigned __int64 bb);

int main()
{
	unsigned int a, b, t1, t2, t3, t4;

	cout << "Press enter to start...";
	cin.ignore();

	t1 = GetTickCount();
	for(a = 0; a < ITERATIONS; ++a)
		b = FirstBit1(1);
	t1 = GetTickCount() - t1;

	t2 = GetTickCount();
	for(a = 0; a < ITERATIONS; ++a)
		b = FirstBit2(1);
	t2 = GetTickCount() - t2;

	t3 = GetTickCount();
	for(a = 0; a < ITERATIONS; ++a)
		b = LastBit1(1);
	t3 = GetTickCount() - t3;

	t4 = GetTickCount();
	for(a = 0; a < ITERATIONS; ++a)
		b = LastBit2(1);
	t4 = GetTickCount() - t4;

	cout << endl << t1 << endl << t2 << "\n\n" << t3 << endl << t4 << "\n\n";

	return 0;
}

const int FirstBit1(const unsigned __int64 bb)
{
	__asm
	{
		bsf		eax, [bb]
		jnz		L10
		bsf		eax, [bb + 4]
		add		eax, 32
L10:
	}
}

const int FirstBit2(const unsigned __int64 bb)
{
	__asm
	{
		bsf		eax, [bb + 4]
		add		eax, 32
		bsf		eax, [bb]
	}
}

const int LastBit1(const unsigned __int64 bb)
{
	__asm
	{
		bsr		eax, [bb + 4]
		jz		L10
		add		eax, 32
		jmp		L11
L10:
		bsr		eax, [bb]
L11:
	}
}

const int LastBit2(const unsigned __int64 bb)
{
	__asm
	{
		bsr		eax, [bb + 4]
		jnz		L10
		bsr		eax, [bb]
		sub		eax, 32
L10:
		add		eax, 32
	}
}

Output on my computer:

Press enter to start...

2383
5909

4747
6529

--------
Regards,
Koundinya

>
>Severi



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.