PC Review


Reply
Thread Tools Rate Thread

BitConverter.ToInt32 - weird optimization?

 
 
=?Utf-8?B?TW9ydGVuIEIuIFBvc3Q=?=
Guest
Posts: n/a
 
      13th Feb 2007
Now, if we take a look at the reflected BitConverter.ToInt32 method it looks
something like this:

public static unsafe int ToInt32(byte[] value, int startIndex)
{
if (value == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
}
if (((ulong) startIndex) >= value.Length)
{

ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex,
ExceptionResource.ArgumentOutOfRange_Index);
}
if (startIndex > (value.Length - 4))
{

ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
}
fixed (byte* numRef1 = &(value[startIndex]))
{
if ((startIndex % 4) == 0)
{
return *(((int*) numRef1));
}
if (BitConverter.IsLittleEndian)
{
return (((numRef1[0] | (numRef1[1] << 8)) | (numRef1[2] <<
0x10)) | (numRef1[3] << 0x18));
}
return ((((numRef1[0] << 0x18) | (numRef1[1] << 0x10)) |
(numRef1[2] << 8)) | numRef1[3]);
}
}

What I don't understand is this:

if ((startIndex % 4) == 0)
{
return *(((int*) numRef1));
}

What prevents me from using this method when the remaining product isn't 0?
We already checked if there is 4 bytes to read so I should be able to.

Cheers

Morten

 
Reply With Quote
 
 
 
 
Jon Skeet [C# MVP]
Guest
Posts: n/a
 
      13th Feb 2007
<=?Utf-8?B?TW9ydGVuIEIuIFBvc3Q=?= <Morten B.
(E-Mail Removed)>> wrote:

<snip>

> What prevents me from using this method when the remaining product isn't 0?
> We already checked if there is 4 bytes to read so I should be able to.


My guess is that "something" doesn't like pointers which aren't aligned
on a word boundary.

--
Jon Skeet - <(E-Mail Removed)>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
 
Reply With Quote
 
=?Utf-8?B?TW9ydGVuIEIuIFBvc3Q=?=
Guest
Posts: n/a
 
      13th Feb 2007


"Jon Skeet [C# MVP]" wrote:

> <=?Utf-8?B?TW9ydGVuIEIuIFBvc3Q=?= <Morten B.
> (E-Mail Removed)>> wrote:
>
> <snip>
>
> > What prevents me from using this method when the remaining product isn't 0?
> > We already checked if there is 4 bytes to read so I should be able to.

>
> My guess is that "something" doesn't like pointers which aren't aligned
> on a word boundary.


You mean double word? It might be that, but it would be super nice to know
WHAT doesn't like it

>
> --
> Jon Skeet - <(E-Mail Removed)>
> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
> If replying to the group, please do not mail me too
>

 
Reply With Quote
 
Jon Skeet [C# MVP]
Guest
Posts: n/a
 
      13th Feb 2007
Morten B. Post <(E-Mail Removed)> wrote:
> > My guess is that "something" doesn't like pointers which aren't aligned
> > on a word boundary.

>
> You mean double word?


Sorry, I'm used to "word" meaning "32 bits" on a 32 bit architecture.
I'd forgotten the curious Windows heritage of it meaning 16 bits...

> It might be that, but it would be super nice to know
> WHAT doesn't like it


I suspect it's *somewhere* in the CLI spec, but I'm feeling too groggy
to check at the minute.

--
Jon Skeet - <(E-Mail Removed)>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
 
Reply With Quote
 
Goran Sliskovic
Guest
Posts: n/a
 
      13th Feb 2007

"Jon Skeet [C# MVP]" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
....
> > What prevents me from using this method when the remaining product isn't

0?
> > We already checked if there is 4 bytes to read so I should be able to.

>
> My guess is that "something" doesn't like pointers which aren't aligned
> on a word boundary.

....

Processors don't like it, it's at least performance penalty, if not an
exception (on some processors). Code seen is on the safe side...

Goran


 
Reply With Quote
 
=?Utf-8?B?TW9ydGVuIEIuIFBvc3Q=?=
Guest
Posts: n/a
 
      13th Feb 2007


"Goran Sliskovic" wrote:

>
> "Jon Skeet [C# MVP]" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> ....
> > > What prevents me from using this method when the remaining product isn't

> 0?
> > > We already checked if there is 4 bytes to read so I should be able to.

> >
> > My guess is that "something" doesn't like pointers which aren't aligned
> > on a word boundary.

> ....
>
> Processors don't like it, it's at least performance penalty, if not an
> exception (on some processors). Code seen is on the safe side...
>
> Goran
>
>
>


I totally understand that. But we're talking about an array of bytes here
which are aligned by 1 byte? So lets say our CPU is using 32 bit cycles - it
would load 4 bytes to the register at a time - the the array offset is wrong
it would actually have to access two different blocks of memory and then
shift away the bits that aren't necessary. Or how do we know that the array
is properly alligned when it consists of. I hope someone can answer this.

On a final note. If .net is adding 3 padded bytes for each byte I'd be
really surprised hehe.
 
Reply With Quote
 
Goran Sliskovic
Guest
Posts: n/a
 
      14th Feb 2007
Morten B. Post wrote:
>

....

>
> I totally understand that. But we're talking about an array of bytes here
> which are aligned by 1 byte? So lets say our CPU is using 32 bit cycles - it
> would load 4 bytes to the register at a time - the the array offset is wrong
> it would actually have to access two different blocks of memory and then
> shift away the bits that aren't necessary. Or how do we know that the array
> is properly alligned when it consists of. I hope someone can answer this.
>
> On a final note. If .net is adding 3 padded bytes for each byte I'd be
> really surprised hehe.


It's not adding 3 padded bytes per byte, rather all allocated buffers
are aligned on 4 byte boundary (even if you allocate 1 byte). OS
allocates all buffers aligned (VirtualAlloc).

From MSDN:
<quote>
VirtualAlloc

Reserves or commits a region of pages in the virtual address space of
the calling process. Memory allocated by this function is automatically
initialized to zero, unless MEM_RESET is specified.

To allocate memory in the address space of another process, use the
VirtualAllocEx function.

LPVOID VirtualAlloc(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect
);

Parameters

lpAddress
[in] The starting address of the region to allocate. If the memory
is being reserved, the specified address is rounded down to the nearest
multiple of the allocation granularity. If the memory is already
reserved and is being committed, the address is rounded down to the next
page boundary. To determine the size of a page and the allocation
granularity on the host computer, use the GetSystemInfo function. If
this parameter is NULL, the system determines where to allocate the region.
</quote>

if ((startIndex % 4) == 0)
{
return *(((int*) numRef1));
}

since buffer is aligned on 4 bytes, all indexes % 4 == 0 are also, so
it's safe to cast to int and return, yielding performance gain. If not,
slow but safe calculation occures.

Regards,
Goran
 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Convert::ToInt32 problem Dave Farquharson Microsoft Dot NET Framework 3 10th May 2008 12:02 AM
Convert.ToInt32(char) omeraa@gmail.com Microsoft Dot NET Framework 1 17th Jan 2006 08:23 AM
(int) or convert.ToInt32 ? =?Utf-8?B?SmFyb2Q=?= Microsoft C# .NET 8 22nd Jun 2005 08:07 PM
String->ToInt32() ... H.B. Microsoft VC .NET 0 15th Mar 2005 04:36 PM
Advantage between (int) and Convert.ToInt32? =?Utf-8?B?Y2hhcmxpZXdlc3Q=?= Microsoft C# .NET 1 16th Feb 2005 07:32 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 08:55 PM.