|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
BitConverter.ToInt32 - weird optimization?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 <=?Utf-8?B?TW9ydGVuIEIuIFBvc3Q=?= <Morten B.
P***@discussions.microsoft.com>> wrote: <snip> > What prevents me from using this method when the remaining product isn't 0? My guess is that "something" doesn't like pointers which aren't aligned > We already checked if there is 4 bytes to read so I should be able to. on a word boundary. -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too "Jon Skeet [C# MVP]" wrote: You mean double word? It might be that, but it would be super nice to know > <=?Utf-8?B?TW9ydGVuIEIuIFBvc3Q=?= <Morten B. > P***@discussions.microsoft.com>> 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. WHAT doesn't like it :) Show quote > > -- > Jon Skeet - <sk***@pobox.com> > http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet > If replying to the group, please do not mail me too > Morten B. Post <MortenBP***@discussions.microsoft.com> wrote:
> > My guess is that "something" doesn't like pointers which aren't aligned Sorry, I'm used to "word" meaning "32 bits" on a 32 bit architecture. > > on a word boundary. > > You mean double word? I'd forgotten the curious Windows heritage of it meaning 16 bits... > It might be that, but it would be super nice to know I suspect it's *somewhere* in the CLI spec, but I'm feeling too groggy > WHAT doesn't like it :) to check at the minute. -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too "Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message Processors don't like it, it's at least performance penalty, if not annews:MPG.203bc890410e0a2698d861@msnews.microsoft.com... .... > > 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. .... exception (on some processors). Code seen is on the safe side... Goran
Show quote
"Goran Sliskovic" wrote: I totally understand that. But we're talking about an array of bytes here > > "Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message > news:MPG.203bc890410e0a2698d861@msnews.microsoft.com... > .... > > > 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 > > > 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. Morten B. Post wrote:
> It's not adding 3 padded bytes per byte, rather all allocated buffers .... > > 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. 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 |
|||||||||||||||||||||||