windows memory allocation

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

windows memory allocation

Post by bob »

I decided a while back to clean up the use of malloc() in Crafty. One key issue is to force the alignment of a malloc()'ed block of memory to a specific value, which could be 64 bytes for hash, 2048 bytes for split blocks, etc. Doing this in a portable way is not so easy, since pointer lengths vary on different machines and doing math on pointers is risky in such a case.

I chose to use a simpler approach for linux, posix_memalign() which is a version of malloc() where you tell it how much memory you want, and what kind of alignment you want. The key issue is freeing such memory. If you try to do a malloc() yourself, and then finagle the pointer to force it to the proper alignment

Code: Select all

   hash = malloc(hash_size + 63) & ~63;
[code]
you get the correct alignment to a cache line boundary, but you can not later use free(hash); since you are not passing the original malloc() address to it.  With posix_memalign() things work just fine and you can free() the memory as in:
[code]
  posix_memalign(&hash, 64, hash_size);

  ...
  ...

  free(hash);
[code]
and things work as you expect.  With the self-aligned approach, you have to save the original pointer from malloc() before you mangle it, and use the original when you want to free memory.

My question is this:  Is there an equivalent to this in windows?  Or do I need to write a pointer-mangling posix_memalign() function that is used for windows, but not for linux???
Dann Corbit
Posts: 12542
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: windows memory allocation

Post by Dann Corbit »

bob wrote:I decided a while back to clean up the use of malloc() in Crafty. One key issue is to force the alignment of a malloc()'ed block of memory to a specific value, which could be 64 bytes for hash, 2048 bytes for split blocks, etc. Doing this in a portable way is not so easy, since pointer lengths vary on different machines and doing math on pointers is risky in such a case.

I chose to use a simpler approach for linux, posix_memalign() which is a version of malloc() where you tell it how much memory you want, and what kind of alignment you want. The key issue is freeing such memory. If you try to do a malloc() yourself, and then finagle the pointer to force it to the proper alignment

Code: Select all

   hash = malloc(hash_size + 63) & ~63;
[code]
you get the correct alignment to a cache line boundary, but you can not later use free(hash); since you are not passing the original malloc() address to it.  With posix_memalign() things work just fine and you can free() the memory as in:
[code]
  posix_memalign(&hash, 64, hash_size);

  ...
  ...

  free(hash);
[code]
and things work as you expect.  With the self-aligned approach, you have to save the original pointer from malloc() before you mangle it, and use the original when you want to free memory.

My question is this:  Is there an equivalent to this in windows?  Or do I need to write a pointer-mangling posix_memalign() function that is used for windows, but not for linux???[/quote]

Use _aligned_malloc for windows:
http://msdn.microsoft.com/en-us/library/8z34s9c6(VS.80).aspx

Beware, posix_memalign is optional for Posix implemenations.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: windows memory allocation

Post by bob »

Dann Corbit wrote:
bob wrote:I decided a while back to clean up the use of malloc() in Crafty. One key issue is to force the alignment of a malloc()'ed block of memory to a specific value, which could be 64 bytes for hash, 2048 bytes for split blocks, etc. Doing this in a portable way is not so easy, since pointer lengths vary on different machines and doing math on pointers is risky in such a case.

I chose to use a simpler approach for linux, posix_memalign() which is a version of malloc() where you tell it how much memory you want, and what kind of alignment you want. The key issue is freeing such memory. If you try to do a malloc() yourself, and then finagle the pointer to force it to the proper alignment

Code: Select all

   hash = malloc(hash_size + 63) & ~63;
[code]
you get the correct alignment to a cache line boundary, but you can not later use free(hash); since you are not passing the original malloc() address to it.  With posix_memalign() things work just fine and you can free() the memory as in:
[code]
  posix_memalign(&hash, 64, hash_size);

  ...
  ...

  free(hash);
[code]
and things work as you expect.  With the self-aligned approach, you have to save the original pointer from malloc() before you mangle it, and use the original when you want to free memory.

My question is this:  Is there an equivalent to this in windows?  Or do I need to write a pointer-mangling posix_memalign() function that is used for windows, but not for linux???[/quote]

Use _aligned_malloc for windows:
http://msdn.microsoft.com/en-us/library/8z34s9c6(VS.80).aspx

Beware, posix_memalign is optional for Posix implemenations.[/quote]

Naturally, windows has to "do it differently".  If you use that call, you can't use free() to release the memory.  Guess I will just write my own malloc_aligned() and use the posix version or the windows version depending.  And then write a free_aligned() to release the memory when needed.
Dann Corbit
Posts: 12542
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: windows memory allocation

Post by Dann Corbit »

bob wrote:
Dann Corbit wrote:
bob wrote:I decided a while back to clean up the use of malloc() in Crafty. One key issue is to force the alignment of a malloc()'ed block of memory to a specific value, which could be 64 bytes for hash, 2048 bytes for split blocks, etc. Doing this in a portable way is not so easy, since pointer lengths vary on different machines and doing math on pointers is risky in such a case.

I chose to use a simpler approach for linux, posix_memalign() which is a version of malloc() where you tell it how much memory you want, and what kind of alignment you want. The key issue is freeing such memory. If you try to do a malloc() yourself, and then finagle the pointer to force it to the proper alignment

Code: Select all

   hash = malloc(hash_size + 63) & ~63;
[code]
you get the correct alignment to a cache line boundary, but you can not later use free(hash); since you are not passing the original malloc() address to it.  With posix_memalign() things work just fine and you can free() the memory as in:
[code]
  posix_memalign(&hash, 64, hash_size);

  ...
  ...

  free(hash);
[code]
and things work as you expect.  With the self-aligned approach, you have to save the original pointer from malloc() before you mangle it, and use the original when you want to free memory.

My question is this:  Is there an equivalent to this in windows?  Or do I need to write a pointer-mangling posix_memalign() function that is used for windows, but not for linux???[/quote]

Use _aligned_malloc for windows:
http://msdn.microsoft.com/en-us/library/8z34s9c6(VS.80).aspx

Beware, posix_memalign is optional for Posix implemenations.[/quote]

Naturally, windows has to "do it differently".  If you use that call, you can't use free() to release the memory.  Guess I will just write my own malloc_aligned() and use the posix version or the windows version depending.  And then write a free_aligned() to release the memory when needed.[/quote]

Here is an interesting article you may find useful:
http://stackoverflow.com/questions/227897/solve-the-memory-alignment-in-c-interview-question-that-stumped-me
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: windows memory allocation

Post by bob »

Dann Corbit wrote:
bob wrote:I decided a while back to clean up the use of malloc() in Crafty. One key issue is to force the alignment of a malloc()'ed block of memory to a specific value, which could be 64 bytes for hash, 2048 bytes for split blocks, etc. Doing this in a portable way is not so easy, since pointer lengths vary on different machines and doing math on pointers is risky in such a case.

I chose to use a simpler approach for linux, posix_memalign() which is a version of malloc() where you tell it how much memory you want, and what kind of alignment you want. The key issue is freeing such memory. If you try to do a malloc() yourself, and then finagle the pointer to force it to the proper alignment

Code: Select all

   hash = malloc(hash_size + 63) & ~63;
[code]
you get the correct alignment to a cache line boundary, but you can not later use free(hash); since you are not passing the original malloc() address to it.  With posix_memalign() things work just fine and you can free() the memory as in:
[code]
  posix_memalign(&hash, 64, hash_size);

  ...
  ...

  free(hash);
[code]
and things work as you expect.  With the self-aligned approach, you have to save the original pointer from malloc() before you mangle it, and use the original when you want to free memory.

My question is this:  Is there an equivalent to this in windows?  Or do I need to write a pointer-mangling posix_memalign() function that is used for windows, but not for linux???[/quote]

Use _aligned_malloc for windows:
http://msdn.microsoft.com/en-us/library/8z34s9c6(VS.80).aspx

Beware, posix_memalign is optional for Posix implemenations.[/quote]

BTW, where did you see the "optional" mentioned?  Man pages here imply it is a part of the standard, period.
Dann Corbit
Posts: 12542
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: windows memory allocation

Post by Dann Corbit »

bob wrote:
Dann Corbit wrote:
bob wrote:I decided a while back to clean up the use of malloc() in Crafty. One key issue is to force the alignment of a malloc()'ed block of memory to a specific value, which could be 64 bytes for hash, 2048 bytes for split blocks, etc. Doing this in a portable way is not so easy, since pointer lengths vary on different machines and doing math on pointers is risky in such a case.

I chose to use a simpler approach for linux, posix_memalign() which is a version of malloc() where you tell it how much memory you want, and what kind of alignment you want. The key issue is freeing such memory. If you try to do a malloc() yourself, and then finagle the pointer to force it to the proper alignment

Code: Select all

   hash = malloc(hash_size + 63) & ~63;
[code]
you get the correct alignment to a cache line boundary, but you can not later use free(hash); since you are not passing the original malloc() address to it.  With posix_memalign() things work just fine and you can free() the memory as in:
[code]
  posix_memalign(&hash, 64, hash_size);

  ...
  ...

  free(hash);
[code]
and things work as you expect.  With the self-aligned approach, you have to save the original pointer from malloc() before you mangle it, and use the original when you want to free memory.

My question is this:  Is there an equivalent to this in windows?  Or do I need to write a pointer-mangling posix_memalign() function that is used for windows, but not for linux???[/quote]

Use _aligned_malloc for windows:
http://msdn.microsoft.com/en-us/library/8z34s9c6(VS.80).aspx

Beware, posix_memalign is optional for Posix implemenations.[/quote]

BTW, where did you see the "optional" mentioned?  Man pages here imply 
it is a part of the standard, period.[/quote]

http://manpages.ubuntu.com/manpages/jaunty/man7/posixoptions.7.html

See also:
http://forum.kde.org/viewtopic.php?f=74&t=47364
http://bugs.opensolaris.org/view_bug.do;jsessionid=e792945695be215c27fa584797?bug_id=6493264

Where it clearly has generated problems.