Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Ryan Joseph


> On Mar 30, 2019, at 5:02 PM, Jonas Maebe  wrote:
> 
> How is this done in the Metal C headers?

Looking this now it appears the padding may be put in the actual vector. Maybe 
those macros put it in there? The fields of the struct need to be aligned on 16 
bytes (4 floats) so. Does c++ even allow padding struct fields or is this kind 
of fringe usage? I thought the compiler already did this so it could just add 
more?

typedef struct
{
// Positions in pixel space
// (e.g. a value of 100 indicates 100 pixels from the center)
vector_float2 position;

// Floating-point RGBA colors
vector_float4 color;
} AAPLVertex;

typedef simd_float2 vector_float2;

/*! @abstract A vector of two 32-bit floating-point numbers.
 *  @description In C++ and Metal, this type is also available as
 *  simd::float2. The alignment of this type is greater than the alignment
 *  of float; if you need to operate on data buffers that may not be
 *  suitably aligned, you should access them using simd_packed_float2
 *  instead.  */
typedef __attribute__((__ext_vector_type__(2))) float simd_float2;

/*! @abstract A vector of four 32-bit floating-point numbers.
 *  @description In C++ and Metal, this type is also available as
 *  simd::float4. The alignment of this type is greater than the alignment
 *  of float; if you need to operate on data buffers that may not be
 *  suitably aligned, you should access them using simd_packed_float4
 *  instead.  */
typedef __attribute__((__ext_vector_type__(4))) float simd_float4;

> 
>> If you saw the original bug report we’re trying to make a custom alignment 
>> (of 4k) for the Metal framework. I propose the syntax because it solves the 
>> problem of how to assign alignment and there is a precedent for it (i.e. 
>> $align).
> 
> No, I missed that. In that case, a vector type won't help. The best way then 
> is, as has been mentioned elsewhere in this thread, a getmem variant that 
> supports allocating memory on an aligned boundary. Similar to how unix 
> platforms have posix_memalign.
> 
> This falls outside the scope of direct support in the language, so a solution 
> like Anthony's is better in this case if you want to encapsulate it 
> completely.

I already started on it before I hit the snag and it’s not an unreasonably 
intrusive thing to allocate the extra padding like I discussed earlier, but it 
would probably require introducing a compiler directive (see $dynarrayalign 
below) and adding alignment information to tarraydef. I’ll post what I finished 
on GitHub if anyone wants to see how invasive the changes are.

There’s a good argument both ways and I guess it comes down to maintaining the 
extra complexity in the compiler. I’m personally happy to use the record since 
it’s feasible in 3.1.1 but I understand users who like the compiler syntax, 
which is cleaner and probably faster.

So what should I do going forward? Should I abandon the idea or do any of the 
other core team members want to me pursue this further?

{$push}
{$dynarrayalign 4096}
type
TIntArray = array of integer;
{$pop}


Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Anthony Walter
Oh and might as well add dot product and cross product for vectors as well

>
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Anthony Walter
On a related note, since a lot of the discussion here seems related to
vector types, I seem to recall someone recently published an mmx,
sse1/2/3/4, simd set of routines related to vector operations. I don't use
much asm other than just being familiar with the basics of ia32 from long
ago, but I do know there have been many enhancements for the instruction
sets I mentioned which specifically greatly increase both the speed and
parallelism of vector operation, including their combination with matrix
math manipulation and vector transforms. I also know that the people in the
mono project enhanced their compiler with special simd vector optimizations:

https://www.mono-project.com/news/2016/12/20/system-numeric-vectors/

Having said that, might it be possible if we could incorporate official
vector and matrix type and optimizations with the compiler? I think
everyone would benefit from officially supported types of this nature that
could have more eyes on them to ensure their operations are best optimized
for the various types of computers and architectures free pascal supports.
I can think of quite a few operations that would benefit from everyone
contributing either their own ideas of the best optimizations or reporting
problems or suggestions.

Here is what I would suggest as a start. Use 4 component float (single and
perhaps additionally double precision) vectors (X, Y, Z, W), 4x4 matrix
type to match.

For vectors we need these operations:
add, subtract, multiply, divide, normalize, transpose

For matrix types we need:
identity, scale, rotate, translate, sheer, multiply (matrix * matrix),
transform (vector * matrix), transpose, invert

That's just a start, but these operations ought to have official simd
support IMO

Thanks
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Jonas Maebe

On 30/03/2019 14:59, Ryan Joseph wrote:




On Mar 30, 2019, at 9:10 AM, Jonas Maebe  wrote:

FPC always aligns data to its alignment as specified by the platform ABI. 
{$align x} can be used to limit this alignment to a lower number. It cannot be 
used to increase it.


This caused us quite a bit of problems with the Metal framework because we 
needed padding fields also.


How is this done in the Metal C headers?


If you saw the original bug report we’re trying to make a custom alignment (of 
4k) for the Metal framework. I propose the syntax because it solves the problem 
of how to assign alignment and there is a precedent for it (i.e. $align).


No, I missed that. In that case, a vector type won't help. The best way 
then is, as has been mentioned elsewhere in this thread, a getmem 
variant that supports allocating memory on an aligned boundary. Similar 
to how unix platforms have posix_memalign.


This falls outside the scope of direct support in the language, so a 
solution like Anthony's is better in this case if you want to 
encapsulate it completely.



Can you give some examples of the vector type? I don’t exactly know what you 
guys are referring to.


A vector type is basically a (fairly small) array of integer or floating 
point types. All current desktop (and many embedded) CPUs have special 
execution units that operate on all elements of such vectors in 
parallel, which means you can get better performance.



Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread J. Gareth Moreton
 I always get nervous of mode switches because it's hard to remember them
or realise they exist, and it feels a little hacky, like it's a kind of
compatibility setting more than anything else.  Like at one point, I
preferred there was an explicit way to set a type's alignment so there's no
ambiguity or risk of bugs if a different setting is used or otherwise
overridden.  e.g.

 type  TVector4f = packed record
     x, y, z, w: Single;
   end align 16;

 Just my thought.

 Kit

 On Sat 30/03/19 17:31 , Mattias Gaertner via fpc-devel
fpc-devel@lists.freepascal.org sent:
 On Sat, 30 Mar 2019 12:57:48 -0400 
 Ryan Joseph  wrote: 

 > > On Mar 30, 2019, at 12:53 PM, Mattias Gaertner via fpc-devel 
 > >  wrote: 
 > > 
 > > I guess you mean auto dereferencing. 
 > > {$ModeSwitch AutoDeref} 
 > 
 > Yeah I just found this by looking around in the compiler. Mind. 
 > Blown. No idea that existed! 

 And some people still ask for more modeswitches... 

 Mattias 
 ___ 
 fpc-devel maillist - fpc-devel@lists.freepascal.org [3] 
 http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[4]">http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel 

 

Links:
--
[1] mailto:r...@thealchemistguild.com
[2] mailto:fpc-devel@lists.freepascal.org
[3] mailto:fpc-devel@lists.freepascal.org
[4] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Mattias Gaertner via fpc-devel
On Sat, 30 Mar 2019 12:57:48 -0400
Ryan Joseph  wrote:

> > On Mar 30, 2019, at 12:53 PM, Mattias Gaertner via fpc-devel
> >  wrote:
> > 
> > I guess you mean auto dereferencing.
> > {$ModeSwitch AutoDeref}  
> 
> Yeah I just found this by looking around in the compiler. Mind.
> Blown. No idea that existed!

And some people still ask for more modeswitches...

Mattias
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Ryan Joseph


> On Mar 30, 2019, at 12:53 PM, Mattias Gaertner via fpc-devel 
>  wrote:
> 
> I guess you mean auto dereferencing.
> {$ModeSwitch AutoDeref}

Yeah I just found this by looking around in the compiler. Mind. Blown. No idea 
that existed!

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Mattias Gaertner via fpc-devel
On Sat, 30 Mar 2019 10:03:12 -0400
Ryan Joseph  wrote:

> > On Mar 30, 2019, at 9:55 AM, Jonas Maebe 
> > wrote: 
> >> You are not required to dereference pointers to write to them.
> >> var
> >>   P: PPoint;
> >> begin
> >>   P := AlignedArray[0];
> >>   P.X := 3; // can be okay
> >>   AlignedArray[0].Y := 4;  // can be okay as well  
> > 
> > That only works in {$mode delphi}  
> 
> Oh that’s why! How does this work in Delphi mode without pointers and
> why wasn’t it added to ObjFPC mode? 

I guess you mean auto dereferencing.
{$ModeSwitch AutoDeref}

> That would have saved me some
> headache in the past if I knew this.

Mattias
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Ryan Joseph


> On Mar 30, 2019, at 9:55 AM, Jonas Maebe  wrote:
> 
>> You are not required to dereference pointers to write to them.
>> var
>>   P: PPoint;
>> begin
>>   P := AlignedArray[0];
>>   P.X := 3; // can be okay
>>   AlignedArray[0].Y := 4;  // can be okay as well
> 
> That only works in {$mode delphi}

Oh that’s why! How does this work in Delphi mode without pointers and why 
wasn’t it added to ObjFPC mode? That would have saved me some headache in the 
past if I knew this.

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread denisgolovan


> 1) In you example you are writing this with normal arrays:
> 
> A[0].X := 0;
> 
> And in my implementation it's exactly the same. Regarding writing the entire 
> type directly
> 
> A[0]^ := V;
> 
> If using the caret symbol ^ or an Item property is a deal breaker, then this 
> can be simplified using a custom smart pointer type similar to how the 
> aligned array type was implemented resulting in the same syntax as in the 
> first example.

Yes, returning temporary smart pointer would do the trick. -1 syntax 
incompatibility then.
I see this as a definite improvement.

> 2) As I've implemented them aligned array is compatible with dynamic arrays. 
> They implicitly convert between the two with no loss of data. If you truly 
> want to share the data within each, then you can define functions to work on 
> referencing the data types they hold, allowing the same function to serve 
> either type.

Well. Converting arrays is too slow to be usable, imho. Think about textures, 
vertex buffers, etc.

> 
> For example:
> 
> procedure VectorTransform(Matrix: TMat4; FirstVertex: PVec3; Count: Integer);
> 
> and then
> 
> Matrix.Rotate(12.5, 0, 0);
> VectorTransform(Matrix, AlignedData[0], AlignedData.Length);
> VectorTransform(Matrix, @DynamicArray[0], Length(AlignedData));
> 
> Or you can even overload VectorTransform if you don't want to see @ symbols.
> 
> procedure VectorTransform(Matrix: TMat4; FirstVertex: var TVec3; Count: 
> Integer); overload;

It's all right and will eventually work. 

But you miss much larger problem - that will require a lot of 
boilerplate/conversion/manual work.
Think about mixing 3 graphical libraries using different array/matrix/vertex 
types. Instead of re-using each others code, one would eventually write 4th 
library.
FPC community is too small to afford such useless combinatorics.

> 
> 3) Regarding Hi, Lo, Length, I prefer to put these functions on types. For 
> example
> 
> for I := A.Lo to A.Hi do A[I].X := I;
> 
> Is that such a deal breaker?

Yes. Generics / generic functions is a big deal.
That would need two different functions for each different _array_ type.

-- 
Regards,
Denis Golovan
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Ryan Joseph


> On Mar 30, 2019, at 9:10 AM, Jonas Maebe  wrote:
> 
> FPC always aligns data to its alignment as specified by the platform ABI. 
> {$align x} can be used to limit this alignment to a lower number. It cannot 
> be used to increase it.

This caused us quite a bit of problems with the Metal framework because we 
needed padding fields also. Is this something that could be added or would it 
be a disaster to add padding to record fields? It sounds like there is already 
a mechanism we could extend but I’m not sure.

> 
>> Why not use a similar directive for array alignment? That would solve the 
>> problem I discovered with insert/concat.
>> {$push}
>> {$align-array 4096}
>> type
>>   TIntArray = array of integer;
>> {$pop}
> 
> Arrays are aligned to the alignment requirements of their components. Again, 
> a vector type would solve this, since vectors have their own alignment 
> requirements in the ABIs.

If you saw the original bug report we’re trying to make a custom alignment (of 
4k) for the Metal framework. I propose the syntax because it solves the problem 
of how to assign alignment and there is a precedent for it (i.e. $align).

Can you give some examples of the vector type? I don’t exactly know what you 
guys are referring to.

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Jonas Maebe

On 30/03/2019 14:42, Anthony Walter wrote:

You are not required to dereference pointers to write to them.

var
   P: PPoint;
begin
   P := AlignedArray[0];
   P.X := 3; // can be okay
   AlignedArray[0].Y := 4;  // can be okay as well


That only works in {$mode delphi}


Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Anthony Walter
You are not required to dereference pointers to write to them.

var
  P: PPoint;
begin
  P := AlignedArray[0];
  P.X := 3; // can be okay
  AlignedArray[0].Y := 4;  // can be okay as well
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Anthony Walter
1) In you example you are writing this with normal arrays:

A[0].X := 0;

And in my implementation it's exactly the same. Regarding writing the
entire type directly

A[0]^ := V;

If using the caret symbol ^ or an Item property is a deal breaker, then
this can be simplified using a custom smart pointer type similar to how the
aligned array type was implemented resulting in the same syntax as in the
first example.

2) As I've implemented them aligned array is compatible with dynamic
arrays. They implicitly convert between the two with no loss of data. If
you truly want to share the data within each, then you can define functions
to work on referencing the data types they hold, allowing the same function
to serve either type.

For example:

procedure VectorTransform(Matrix: TMat4; FirstVertex: PVec3; Count:
Integer);

and then

Matrix.Rotate(12.5, 0, 0);
VectorTransform(Matrix, AlignedData[0], AlignedData.Length);
VectorTransform(Matrix, @DynamicArray[0], Length(AlignedData));

Or you can even overload VectorTransform if you don't want to see @
symbols.

procedure VectorTransform(Matrix: TMat4; FirstVertex: var TVec3; Count:
Integer); overload;

3) Regarding Hi, Lo, Length, I prefer to put these functions on types. For
example

for I := A.Lo to A.Hi do A[I].X := I;

Is that such a deal breaker?
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Jonas Maebe

On 30/03/2019 14:07, Ryan Joseph wrote:


I never got $align to work for records.


FPC always aligns data to its alignment as specified by the platform 
ABI. {$align x} can be used to limit this alignment to a lower number. 
It cannot be used to increase it.



Why not use a similar directive for array alignment? That would solve the 
problem I discovered with insert/concat.

{$push}
{$align-array 4096}
type
   TIntArray = array of integer;
{$pop}


Arrays are aligned to the alignment requirements of their components. 
Again, a vector type would solve this, since vectors have their own 
alignment requirements in the ABIs.



Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Ryan Joseph


> On Mar 30, 2019, at 12:56 AM, Anthony Walter  wrote:
> 
> So the default property indexer returns references and not values. If you 
> want values specifically you can use the Item property indexer.
> 
> This way we can either access fields directly on the items withing the array 
> like so:
> 
> A[0].X := SomeValue;
> 

Yes, but it’s a pointer so we need to dereference with ^.

A[0]^.X := 1;

That’s the one difference which we can’t resolve now. Basically we would need a 
“var” result introduced into the language. C++ has that feature so maybe it’s 
not crazy to implement in Pascal.

int& getter() {
  return i;
}

function getInt: integer; var;
begin
  result := i;
end;

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread denisgolovan
Exactly, alignment might be well attached to array or array element type.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Ryan Joseph


> On Mar 29, 2019, at 5:30 PM, denisgolovan  wrote:
> 
> Also I'd like to get an idea how this functionality is to play with existing 
> alignment directives for records.

I never got $align to work for records. Isn’t that supposed to pad the fields 
to 16 bytes? Doesn’t work for me.

{$push}
{$align 16}
type
  TVertex = record
pos: TVec2;
col: TVec2;
  end;
{$pop}

Why not use a similar directive for array alignment? That would solve the 
problem I discovered with insert/concat.

{$push}
{$align-array 4096}
type
  TIntArray = array of integer;
{$pop}

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread denisgolovan
Hi Jonas

Vector type in FPC is too good to be true.
I didn't dare to dream about it so far :)

BR,
Denis
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread denisgolovan
Hi  Anthony

> The more that I think about it, the more I am believe that using my approach 
> is probably the best solution. Hear me out please.
> 
> First, it would be fairly easy to implement copy on write logic with a custom 
> record class.
> 
> Second, because it's Pascal code, it's entirely possible to fully customize 
> how it operates now and into the future, without the need to modify the 
> compiler. Suppose later you decide that also want the ability allocate the 
> storage memory of using the same array interface, but with a vertex buffer 
> object as the mechanism for allocating storage. Maybe at a later time you 
> want to allow an arrays type to back a memory mapped file.
> 
> In all cases, user code would be the proper avenue to implement these 
> features. Unless these is some special feature unique to an intrinsic type 
> that makes working with a user code type significantly more difficult, why 
> bother adding more complexity to the compiler and more complexity rigidly 
> into the built in types?
> 
> Now that we have management operators, type helpers, generics, 
> implicit/explicit conversions, and operator overloading, why not use what we 
> already have and make it better? Can you, or anyone for that matter, find a 
> real problem with a type or other construct that user code solution can solve 
> trivially with approximately the same syntax? If so then yes I am all for 
> addling to the language and compiler. In all other cases when can use what 
> the nice compiler and language developers have created for us and do everyone 
> a favor by reporting and helping to fix the bugs those features might still 
> have.

Yes. 
I am all for custom/user implementation in case it can be used everywhere 
together/interchangeably with native dynamic arrays. 
However FPC typing does not seem to cope with that (currently?).

1. e.g. primitive types (integers, floats) and records still need different 
handling in your TAlignedArray:

A[0]^:=0; 
A.Item[0]:=0;
vs
A[0].X:=0;

Standard arrays support A[0]:=0 and A[0].X:=0 via their compiler magic.

2. TAlignedArray memory layout can't be made compatible with dynamic arrays. 
Thus no existing functions accepting dynamic arrays would work with 
TAlignedArray and vice versa. 
And that's a huge deal as it just greatly increases fragmentation and messes 
with code re-use between libraries.
Imho, Pascal is too good to follow into C/C++ custom arrays hell.

3. Does not support standard way of dealing with array like @A[0], High(A), 
Low(A), Length(A), etc. 
Think about generic functions accepting both standard dynamic array and your 
custom array/vector.

Another minor issue is that your TAlignedArray is semantically more like Rust's 
Vec. 
It lacks public SetLength, but has Push/Pop/Clear. Thus it behaves differently 
to FPC array.

-- 
Regards,
Denis Golovan
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Jonas Maebe

On 29/03/2019 22:30, denisgolovan wrote:

Could we discuss more options here?


Since this is mostly about vectors, I think the best approach is to add 
an actual vector type to the compiler (Vector Pascal may serve as 
inspiration on how to integrate it in the language). Anything from 
dynamic arrays to records to variables could then automatically align 
them to whatever is required by the target platform.



Jonas
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-30 Thread Anthony Walter
Denis,

The more that I think about it, the more I am believe that using my
approach is probably the best solution. Hear me out please.

First, it would be fairly easy to implement copy on write logic with a
custom record class.

Second, because it's Pascal code, it's entirely possible to fully customize
how it operates now and into the future, without the need to modify the
compiler. Suppose later you decide that also want the ability allocate the
storage memory of using the same array interface, but with a vertex buffer
object as the mechanism for allocating storage. Maybe at a later time you
want to allow an arrays type to back a memory mapped file.

In all cases, user code would be the proper avenue to implement these
features. Unless these is some special feature unique to an intrinsic type
that makes working with a user code type significantly more difficult, why
bother adding more complexity to the compiler and more complexity rigidly
into the built in types?

Now that we have management operators, type helpers, generics,
implicit/explicit conversions, and operator overloading, why not use what
we already have and make it better? Can you, or anyone for that matter,
find a real problem with a type or other construct that user code solution
can solve trivially with approximately the same syntax? If so then yes I am
all for addling to the language and compiler. In all other cases when can
use what the nice compiler and language developers have created for us and
do everyone a favor by reporting and helping to fix the bugs those features
might still have.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] Aligned dynamic arrays

2019-03-30 Thread denisgolovan
Hi all

Sorry for possible starting a new thread as I've just managed to subscribe to 
the list.

Could we discuss more options here?

Maybe separate aligned array is a better alternative? 

I mean a new type fully backward compatible with dynamic arrays, but with 
additional requirements (more specialized that is)?
Like some interface (similar to memory manager record) for reallocating, 
deallocating, copy-on-write handling, etc. 
Ideally some state would be allowed as well, thus interface type.
This way dynamic arrays might be more flexible. e.g. think of mmapped arrays on 
disk implementation support (requires extra state like file handles, etc.).
I reckon it would require more changes to compiler though.

Also I'd like to get an idea how this functionality is to play with existing 
alignment directives for records.

-- 
Regards,
Denis Golovan
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-29 Thread Anthony Walter
Inside the type I have:

  TAlignedArray = record
  public
type
  TReference = ^T;
  TValue = T;
...
procedure Push(const Item: TValue);
function Pop: TValue;
property Length: Integer read FLength write SetLength;
property Reference[Index: Integer]: TReference read GetReference;
default;
property Item[Index: Integer]: TValue read GetItem write SetItem;
...
  end;

So the default property indexer returns references and not values. If you
want values specifically you can use the Item property indexer.

This way we can either access fields directly on the items withing the
array like so:

A[0].X := SomeValue;

Or if you need fast access to quickly populate the values, support we want
to write 3 component vertex data, you could write:

type
  TVertexBuffer = type TAlignedArray;
var
  Buffer: TVertexBuffer;
  V: TVertexBuffer.TReference;
begin
  Buffer.Length := VertexCount(ModelStream);
  V := Buffer[0];
  for I := 1 to Buffer.Length do
  begin
V.X := ReadX(ModelStream);
V.Y := ReadY(ModelStream);
V.Z := ReadZ(ModelStream);
Inc(V);
  end;
  ...
end;

Which probably ends up being faster than continually accessing array
dynamic values by index.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-29 Thread Ryan Joseph


> On Mar 29, 2019, at 9:15 PM, Anthony Walter  wrote:
> 
> Ryan, actually ...
> 
> A.Length := 1;
> A[0].X := 100;
> 
> ... does work in my implementation.

Really, how? [] property uses a getter which copies the array right? I’mm not 
aware of how to do this in Pascal without pointers.

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-29 Thread Anthony Walter
Ryan, actually ...

A.Length := 1;
A[0].X := 100;

... does work in my implementation.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-29 Thread Ryan Joseph


> On Mar 29, 2019, at 5:25 PM, Sven Barth via fpc-devel 
>  wrote:
> 
> Ignoring something is not an answer. At least there'd need to be a runtime 
> error.
> 
> Thinking about it maybe it would be better to follow Anthony's idea with the 
> record and not try to adjust/extend a language mechanism that wasn't geared 
> for that.

Biggest problems with records is that we can’t make arrays of records because 
the [] property copies the record with the getter (my other email on this never 
got posted). If there was a feasible way to fix that problem then dynamic 
arrays would be nearly obsolete anyways (probably still faster though).

var
 A: TAlignedArray;
begin
 A.Length := 1;
 A[0].x := 100; // Doesn’t work, writes to a copy and never mutates the 
underlying structure.

Is there no other way to specify alignment? It would be ugly but a compiler 
directive could be used.

var
 {$push}
 {$dynamic-array-align 4096}
 a: array of integer;
 {$pop}
begin
  SetLength(a,10); // just use normal SetLength now

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-29 Thread Marco van de Voort



Op 3/28/2019 om 11:40 PM schreef Anthony Walter:
Here is a brief follow up. I am working on other projects at the 
moment, but I am confident this a simple solution. Please tell me if 
this somehow will not fit you needs.

My needs are simple:

- auto clean like dynamic arrays.
- preferably transparent with all existing mechanisms.
- performance is important so no getters and setters (the units are 
pixels, and getters and setters in such cases slow down too much).
- I mostly align for SSE/AVX not DMA, so my alignment is typically 
64byte, I'd rather not use special functions that don't allocate via the 
pascal suballocator, that would only

increase fragmentation

However currently I have stowed the alignment requirement away in a few 
classes which are manually specialized versions of a generic one for 
different pixel size derive/specialize (*), so while I'm an alignment user,

I'm not the best motivation to pull it in language.


(*) 8-bit grayscale and  24-bit RGB have manually specialized classes, 
the rest uses an generic, which optimizes not as well in Delphi, but 
good enough for all but the most extreme speed.  The 24-bit RGB case is 
also due to bugs in older (<=XE6) Delphis that

don't deal well with pointer math of 3-byte types.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-29 Thread Sven Barth via fpc-devel

Am 29.03.2019 um 17:53 schrieb Ryan Joseph:

First minor snag, fpc_dynarray_insert, fpc_dynarray_concat can allocate new 
arrays like SetLength can. Do we need to make aligned variants for these also? 
Using array + operators there is no possibility to set alignment.

var
   a, b: array of integer;
begin
   a += [1]; // no way to set alignment for a

   insert(1, b, 0); // no way to set alignment for b
end.

Some options:

1) ignore the problem
2) make extra syntax like:

a: array of integer; alignment = 64;

3) make another function to allocate an empty array that sets alignment

SetAlignment(a, 64);
An empty array is Nil, changing that would lead to a whole different can 
of worms.

4) for insert/concat make variants like InsertAligned() and ignore + operators 
for aligned arrays
Ignoring something is not an answer. At least there'd need to be a 
runtime error.


Thinking about it maybe it would be better to follow Anthony's idea with 
the record and not try to adjust/extend a language mechanism that wasn't 
geared for that.


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays / Maybe implement in mem-mgr?

2019-03-29 Thread Ryan Joseph


> On Mar 29, 2019, at 1:21 PM, Martin Frb  wrote:
> 
> Question: Should the alignment be "user data" or "type info".
> Does it need to be determined at runtime, and set to different values (for 
> the same type/variable) at runtime?

I’m just doing what Sven said I could do, which is store the info in the 
dynamic array header and add a “SetLengthAligned” intrinsic. Maybe the new 
problem changes things though.

As for the memory manager I’m not sure that helps because of how the dynamic 
arrays are already implemented. It would have to be extended to return an 
aligned block that had x number of bytes directly before it. No idea if that’s 
feasible for memory managers.

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays / Maybe implement in mem-mgr?

2019-03-29 Thread Martin Frb

On 29/03/2019 17:53, Ryan Joseph wrote:

First minor snag, fpc_dynarray_insert, fpc_dynarray_concat can allocate new 
arrays like SetLength can. Do we need to make aligned variants for these also? 
Using array + operators there is no possibility to set alignment.

1) ignore the problem
2) make extra syntax like:

a: array of integer; alignment = 64;

3) make another function to allocate an empty array that sets alignment

SetAlignment(a, 64);
4) for insert/concat make variants like InsertAligned() and ignore + operators 
for aligned arrays



Question: Should the alignment be "user data" or "type info".
Does it need to be determined at runtime, and set to different values 
(for the same type/variable) at runtime?


If not, i.e. if a specific variable always needs 4k alignment, would it 
not be more logical to make it part of the type?

   type TFoo = array [x..y] of byte aligned 4096;

Of course that does not change the above problem.
The (current or fixed) alignment needs to be stored, so concat can 
retrieve it and honour it.

Stored either in the header or the RTTI type info



Question 2:
Would it not be more efficient, if the alignment would happen in the 
memory manager?
Then no over-allocation would be needed. And the memory that is skipped 
in front of the array could be used for other data.


The memory manager would need 2 new methods:
AllocMemAtAllignment
FreeMemWithAllignment

So the array still needs to know, it was allocated with Allignment and 
call the correct  FreeMemWithAllignment.
As a default for all memory manager AllocMemAtAllignment could do the 
over-allocate, and return the correct pointer, with the mem-managers 
align header.

Individual MemManagers can then be optimized.

pseudo code for AllocMemAtAllignment
  mem := alloc(size+align+sizeof(MemMgrAlignHeader))
  result := getNextAlignedAddr(mem+sizeof(MemMgrAlignHeader))
  (result-sizeof(MemMgrAlignHeader)) ^.RealAllocAddr := mem;

The result looks then like
  mem
 // padding
  result - header:
 RealAllocAddr
  result
    // At least size bytes

So pretty much what would have happened in the array code. But moved to 
the mem-manager.

So it can be:
a) re-used for other types or even called by usercode
b) a mem-manager that can get the aligned address without padding, can 
be optimized, and return a normal block of memory

  (does not even need the MemMgrAlignHeader)











___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-29 Thread Ryan Joseph
First minor snag, fpc_dynarray_insert, fpc_dynarray_concat can allocate new 
arrays like SetLength can. Do we need to make aligned variants for these also? 
Using array + operators there is no possibility to set alignment.

var
  a, b: array of integer;
begin
  a += [1]; // no way to set alignment for a

  insert(1, b, 0); // no way to set alignment for b
end.

Some options:

1) ignore the problem
2) make extra syntax like: 

a: array of integer; alignment = 64;

3) make another function to allocate an empty array that sets alignment

SetAlignment(a, 64);
4) for insert/concat make variants like InsertAligned() and ignore + operators 
for aligned arrays

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-29 Thread Anthony Walter
Gareth,

There is a bounty for this? I wonder if my solution is acceptable.

Also, my solution, or any for that matter, could be enhanced to make the
alignment size configurable per each array aligned array. That is, memory
alignment starting position and page size could be defined by each array.
This would allow for more flexibility and would be trivial enough to adapt
to what I've provided.

Finally, these methods could be added to the type, making it like a super
array or list:

{ Returns the lower bounds of the list }
function Lo: Integer;
{ Returns the upper bounds of the list }
function Hi: Integer;
{ Reverses the items in the list }
procedure Reverse;
{ Swap two items by index in the list }
procedure Exchange(A, B: Integer);
{ Adds and item to the end of the list }
procedure PushRange(const Collection: array of T);
{ Remove an item randomly from the list }
function PopRandom: T;
{ Return a copy of the list with items passing through a filter }
function Filter(Func: TFilterFunc): TArrayList;
{ Return the first item matching a condition }
function FirstOf(Func: TFilterFunc): T;
{ Removes an item by index from the list and decreases the count by one
}
procedure Delete(Index: Integer);
{ Sort the items using a comparer }
procedure Sort(Order: TSortingOrder = soAscend; Comparer: TCompare =
nil);
{ Attempt to find the item using DefaultCompare }
function IndexOf(const Item: T): Integer;
{ Join a the array into a string using a separator }
function Join(const Separator: string; Convert: TConvertString =
nil): string;
{ Returns true if ther are no items in the list }
property IsEmpty: Boolean read GetIsEmpty;
{ First item in the list }
property First: T read GetFirst write SetFirst;
{ Last item in the list }
property Last: T read GetLast write SetLast;
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-29 Thread J. Gareth Moreton
 I wonder if there's any incentive to have such a feature in-built in the
compiler.  The bounty on #34031 has probably expired by now.  If not,
then your unit would be a great addition.
 Page-aligned memory is probably something that warrants further discussion
with the core team.

 Gareth aka. Kit

 On Fri 29/03/19 05:01 , "Anthony Walter" sys...@gmail.com sent:
 Here is the full implementation of aligned arrays, let me know if it works
for you.
 https://www.getlazarus.org/arrays/ [1]

 Here is another example:
 uses  AlignArrays;
  procedure Test;var
   VertexData: TAlignedArray;  V: PVec3;  I: Integer;begin 
VertexData.Length := 100; // page sized and aligned memory allocated here
  V := VertexData[0]; // get a reference to the first item  for I := 0 to
V.Length - 1 do  begin    V^ := ComputeVertex(I); // write to vertex
data faster via a pointer
     Inc(V);  end;   for V in VertexData do // array like enumerators
are supported    PrintVertex(V);  V.Item[6] :=
ComputeVertex(Random(100)); // you can write directly using this syntax 
V[7]^ := ComputeVertex(Random(100)); // or write by dereferencing  the
default indexer end; // there is no need to free the memory, it is taken
care of for you by finalize
  

Links:
--
[1] https://www.getlazarus.org/arrays/
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-28 Thread Anthony Walter
Here is the full implementation of aligned arrays, let me know if it works
for you.

https://www.getlazarus.org/arrays/

Here is another example:

uses
  AlignArrays;

procedure Test;
var
  VertexData: TAlignedArray;
  V: PVec3;
  I: Integer;
begin
  VertexData.Length := 100; // page sized and aligned memory allocated here
  V := VertexData[0]; // get a reference to the first item
  for I := 0 to V.Length - 1 do
  begin
V^ := ComputeVertex(I); // write to vertex data faster via a pointer
Inc(V);
  end;
  for V in VertexData do // array like enumerators are supported
PrintVertex(V);
  V.Item[6] := ComputeVertex(Random(100)); // you can write directly using
this syntax
  V[7]^ := ComputeVertex(Random(100)); // or write by dereferencing  the
default indexer
end; // there is no need to free the memory, it is taken care of for you by
finalize
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-28 Thread J. Gareth Moreton
 Just to add a minor thing... while usually you don't have to align memory
any more coarsely than 16 bytes for XMM, 32 bytes for YMM and 64 bytes for
ZMM, the 4 kB granularity is useful for paging, especially if you're
reading or writing to a swap file.  An entire library of functions for
such memory management and alignment would definitely be beneficial. 
Using FastMM4 if at all possible is even better.
 And that record definition is pretty nice, I have to say!
 Gareth aka. Kit

 On Thu 28/03/19 22:40 , Anthony Walter sys...@gmail.com sent:
 Here is a brief follow up. I am working on other projects at the moment,
but I am confident this a simple solution. Please tell me if this somehow
will not fit you needs.
 Create a new type that is compatible with Array where Array = type array
of T.Define implcit conversions between the to types and similar
methodsCreate a Push and Pop methods, well as a read write Length property
and two indexers. Indexer named Reference is default and provides a memory
reference to TnIndexer named Item is available and provides a copy of Tn

 So we would have ...
   TAlignedArray = record
     type TReference = ^T;    type TValue = T;    FPage: Pointer; 
  FLength: Integer;    procedure SetLength(Value: Integer);   
function GetReference(Index: Integer): TReference;     function
GetItem(Index: Integer): TValue;    procedure SetItem(Index: Integer;
const Value: TValue);  public    procedure Push(const Item: TValue); 
  procedure Pop: TValue;    property Length: Integer read FLength write
SetLength;    property Reference[Index: Integer]: TValue read
GetReference; default;    property Item[Index: Integer]: TValue read
GetValue write SetValue;
  Examples usages:
 type  TVertexArray = TAlignedArray;
 // and later
 var  Vertices: TVertexArray;begin
   Vertices.Length = 1000; // okay, request a page aligned memory 
Vertices[0].X := X; // okay, we are working with references 
Vertices.Item[1] := Vec3(X, Y, Z); // okay, we are setting a value 
Vertices.Length = 0; // clean up

 When the vertex array need to grow, it uses the POSIX posix_memalign (or
the _aligned_malloc on Windows) to request a 4 KB aligned and sized page
adequate to contain all the items. The newish allocate and release
mechanisms can further be used to simply the management of the
TAlignedArray type. ___
 fpc-devel maillist - fpc-devel@lists.freepascal.org [1]
 http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
[2]">http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

 

Links:
--
[1] mailto:fpc-devel@lists.freepascal.org
[2] http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-28 Thread Anthony Walter
Here is a brief follow up. I am working on other projects at the moment,
but I am confident this a simple solution. Please tell me if this somehow
will not fit you needs.

Create a new type that is compatible with Array where Array = type
array of T.
Define implcit conversions between the to types and similar methods
Create a Push and Pop methods, well as a read write Length property and two
indexers.
Indexer named Reference is default and provides a memory reference to Tn
Indexer named Item is available and provides a copy of Tn

So we would have ...

  TAlignedArray = record
type TReference = ^T;
type TValue = T;
FPage: Pointer;
FLength: Integer;
procedure SetLength(Value: Integer);
function GetReference(Index: Integer): TReference;
function GetItem(Index: Integer): TValue;
procedure SetItem(Index: Integer; const Value: TValue);
  public
procedure Push(const Item: TValue);
procedure Pop: TValue;
property Length: Integer read FLength write SetLength;
property Reference[Index: Integer]: TValue read GetReference; default;
property Item[Index: Integer]: TValue read GetValue write SetValue;

Examples usages:

type
  TVertexArray = TAlignedArray;

// and later

var
  Vertices: TVertexArray;
begin
  Vertices.Length = 1000; // okay, request a page aligned memory
  Vertices[0].X := X; // okay, we are working with references
  Vertices.Item[1] := Vec3(X, Y, Z); // okay, we are setting a value
  Vertices.Length = 0; // clean up


When the vertex array need to grow, it uses the POSIX posix_memalign (or
the _aligned_malloc on Windows) to request a 4 KB aligned and sized page
adequate to contain all the items. The newish allocate and release
mechanisms can further be used to simply the management of the
TAlignedArray type.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-28 Thread Sven Barth via fpc-devel

Am 28.03.2019 um 15:17 schrieb Ryan Joseph:



Also I don't think that a simple "do alignment or not" will be sufficient. What 
kind of alignment do you pick? What if the user needs more alignment? So it would 
probably be best to add a new SetLengthAligned of which the second argument is the 
alignment followed by the lengths.

That’s correct, there’s an alignment parameter also, not just a boolean. The 
header may need to include the desired alignment also for copy operations but 
I’m not sure yet.

Since the offset is going to be part of the header now (and possibly the 
desired alignment) does it matter that this will affect all dynamic arrays? 
It’s probably only 4 bytes but still worth considering.
I'm not a fan of introducing a separate header for this. And abusing 
some bits of the existing fields as flags just means that other parts of 
dynarr.inc have to be touched even though we avoided that by ordering it 
as [padding][header][data].

In dynarr.inc you then add a new setlength variant that takes an additional 
alignment parameter while the old one without alignment calls the new one with 
alignment 1.

Note: the compiler can call the new one for both variants, but the old one is 
required for bootstrapping, so you could surround that with {$if not 
defined(ver3_0) and not defined(ver3_2)}.

You mean if the compiler is < 3.0 then don’t parse the new SetLength variant?


No, I mean it like this:

=== code begin ===

procedure int_dynarray_setlength_aligned(var p : pointer;pti : pointer;
  dimcount : sizeint;dims : pdynarrayindex;alignment : 
longint);[external name 'FPC_DYNARR_SETLENGTH_ALIGNED'];


{$if defined(ver3_0) or defined(ver3_2)}
procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
  dimcount : sizeint;dims : 
pdynarrayindex);[Public,Alias:'FPC_DYNARR_SETLENGTH']; compilerproc;

begin
  int_dynarray_setlength_aligned(p,pti,dimcount,dims,1);
end;
{$endif}

=== code end ===

If the compiler always calls the aligned variant (on call less) then the 
one without alignment is only required for bootstrapping with 3.0.4 or 3.2.


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-28 Thread Sven Barth via fpc-devel

Am 28.03.2019 um 18:41 schrieb Ryan Joseph:

Now I’m using “cd /rtl; make all FPC=/path/to/compiler” to build the RTL but 
this is obviously slow and unnecessary. Is there a quicker way to build just 
the unit which contains dynarr.inc and have all the objects files to be put in 
the correct location?
I don't see where this is slow... Even on my old PowerBook that time 
doesn't hinder me that much.


That said, you could try "make ../units/-/system.ppu" 
in the RTL directory of your target OS (e.g. for Linux in the rtl/linux 
directory and for Mac OS X in the rtl/darwin directory).


Regards,
Sven
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-28 Thread Anthony Walter
Ryan, this is just a thought. Do you need the flat memory address to start
on an even 4 KB boundary or are you okay with the memory address starting
at any DWORD address and spanning an even 4 KB after that address?

In the latter case I have an easy solution for you. If the former I am
unsure how to allocate memory at a specific address but could create a
simple enough solution which may waste some space at the start yet give the
array a starting address of a number divisible evenly by 4 KB. Let me know
and I'll write an implementation which I am pretty sure you'll find either
solution more than adequate.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-28 Thread Christo Crause
On Thu, 28 Mar 2019, 20:34 Ryan Joseph,  wrote:

> Now I’m using “cd /rtl; make all FPC=/path/to/compiler” to build the RTL
> but this is obviously slow and unnecessary. Is there a quicker way to build
> just the unit which contains dynarr.inc and have all the objects files to
> be put in the correct location?
>

Dynarr.inc gets pulled into system.pp via system.inc. So the whole RTL
should be rebuilt anyway. Except of course if you only want to test your
changes without requiring anything else from the RTL. Then you can look at
the compiler command generated by make, system is the first unit to get
compiled, and copy that. There may of course be other ways too.
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-28 Thread Ryan Joseph
Now I’m using “cd /rtl; make all FPC=/path/to/compiler” to build the RTL but 
this is obviously slow and unnecessary. Is there a quicker way to build just 
the unit which contains dynarr.inc and have all the objects files to be put in 
the correct location?


Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-28 Thread Ryan Joseph


> On Mar 28, 2019, at 4:17 AM, Sven Barth via fpc-devel 
>  wrote:
> 
> The order should be 
> 
> [padding] [header] [data]
> 
> with the offset being part of the header. This way you reduce the changes 
> needed to only those that allocate/free an array.

Yeah that’s probably the better idea because it’s less intrusive.

> Also I don't think that a simple "do alignment or not" will be sufficient. 
> What kind of alignment do you pick? What if the user needs more alignment? So 
> it would probably be best to add a new SetLengthAligned of which the second 
> argument is the alignment followed by the lengths. 

That’s correct, there’s an alignment parameter also, not just a boolean. The 
header may need to include the desired alignment also for copy operations but 
I’m not sure yet.

Since the offset is going to be part of the header now (and possibly the 
desired alignment) does it matter that this will affect all dynamic arrays? 
It’s probably only 4 bytes but still worth considering.

> 
> In dynarr.inc you then add a new setlength variant that takes an additional 
> alignment parameter while the old one without alignment calls the new one 
> with alignment 1.
> 
> Note: the compiler can call the new one for both variants, but the old one is 
> required for bootstrapping, so you could surround that with {$if not 
> defined(ver3_0) and not defined(ver3_2)}.

You mean if the compiler is < 3.0 then don’t parse the new SetLength variant?

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-28 Thread Sven Barth via fpc-devel
Ryan Joseph  schrieb am Do., 28. März 2019,
03:01:

> Here’s the basic structure:
>
> [header][padding][offset][head]
>
> [head] being the start of the elements (the pointer to the first element
> of the array) and aligned to the requested amount. Keep in mind the head is
> the pointer which is passed around so we need to subtract back from that in
> order to access the header, which contains the array high value and the
> refcount.
>

The order should be

[padding] [header] [data]

with the offset being part of the header. This way you reduce the changes
needed to only those that allocate/free an array.


> Look at the dynarr.inc in the /rtl directory to see what I’m talking
> about. Pretty hard to explain without seeing how Sven did things. :)
>

Most of that isn't my code. I only added Insert, Delete and Concat.


> >
> > The comment:
> > As for extending the array header, maybe introduce a new data type
> "aligned array".
> > So normal arrays do not have that field in there header.
>
> The plan was to make a “SetLengthAligned” or add an extra parameter to
> “SetLength”, i.e, SetLength(arr,100,true). I have no preference, what ever
> the compiler team wants.
>

Extending SetLength is not a good idea as that can take multiple lengths
for multi dimensional arrays.

Also I don't think that a simple "do alignment or not" will be sufficient.
What kind of alignment do you pick? What if the user needs more alignment?
So it would probably be best to add a new SetLengthAligned of which the
second argument is the alignment followed by the lengths.

In dynarr.inc you then add a new setlength variant that takes an additional
alignment parameter while the old one without alignment calls the new one
with alignment 1.

Note: the compiler can call the new one for both variants, but the old one
is required for bootstrapping, so you could surround that with {$if not
defined(ver3_0) and not defined(ver3_2)}.

Regards,
Sven

>
___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-27 Thread Ryan Joseph


> On Mar 27, 2019, at 9:13 PM, Martin Frb  wrote:
> 
> 2 Ideas, well 1 Idea, 1comment...
> 
> The Idea:
> Would it not be easier to:
> - allocate mem, with extra space for align, unless memmanager can handle 
> align.
> - return the alligned pointer for the array, so all array ops will work 
> exactly as they currently do
> - prefix/extend the array header by a field "OffsetToMemAlloc" (that is the 
> reverse, of what I understand your padding would do, but still can be a 
> positive number, the code knows to subtract it where needed)
> 
> This field would allow to correctly get the memory for re-alloc/free 
> operations.

I think we’re basically talking about the same thing but it’s hard to know 
without seeing code. The biggest challenge is that in order to get the array 
header you need to subtract from the “head" (the start of the elements). Right 
now it’s easy because you just subtract the size of the header but if the head 
is now aligned and 100’s of bytes away from the start of the header then you 
need to subtract that amount also. In fact technically speaking the offset 
field is adjacent to the start of elements and could be many bytes away from 
the actual header.

Here’s the basic structure:

[header][padding][offset][head]

[head] being the start of the elements (the pointer to the first element of the 
array) and aligned to the requested amount. Keep in mind the head is the 
pointer which is passed around so we need to subtract back from that in order 
to access the header, which contains the array high value and the refcount.

Look at the dynarr.inc in the /rtl directory to see what I’m talking about. 
Pretty hard to explain without seeing how Sven did things. :)

> 
> The comment:
> As for extending the array header, maybe introduce a new data type "aligned 
> array".
> So normal arrays do not have that field in there header.

The plan was to make a “SetLengthAligned” or add an extra parameter to 
“SetLength”, i.e, SetLength(arr,100,true). I have no preference, what ever the 
compiler team wants.

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


Re: [fpc-devel] Aligned dynamic arrays

2019-03-27 Thread Martin Frb

On 28/03/2019 00:43, Ryan Joseph wrote:

I would like to attempt to implement this feature request 
(https://bugs.freepascal.org/view.php?id=34031 for my boss) which has the 
SetLength intrinsic return aligned memory. We need this for the Metal framework 
which requires all vertex buffer memory to aligned on 4k boundaries so we can’t 
use dynamic arrays in their current form (see the bug report for example code).

I’ve looked at the dynamic array implementation (dynarr.inc) and it appears 
that I could over allocate and extend the header (tdynarray) to include an 
extra field which stores the amount of padding until the actual array elements 
start (which is aligned). It would complicit the code to some extent however 
because the current design relies on lots of pointer math.

Is this ok that I add this? Marco said in the comments there was a need so I 
assume this is a go but I wanted to ask first.


2 Ideas, well 1 Idea, 1comment...

The Idea:
Would it not be easier to:
- allocate mem, with extra space for align, unless memmanager can handle 
align.
- return the alligned pointer for the array, so all array ops will work 
exactly as they currently do
- prefix/extend the array header by a field "OffsetToMemAlloc" (that is 
the reverse, of what I understand your padding would do, but still can 
be a positive number, the code knows to subtract it where needed)


This field would allow to correctly get the memory for re-alloc/free 
operations.


The comment:
As for extending the array header, maybe introduce a new data type 
"aligned array".

So normal arrays do not have that field in there header.

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel


[fpc-devel] Aligned dynamic arrays

2019-03-27 Thread Ryan Joseph
I would like to attempt to implement this feature request 
(https://bugs.freepascal.org/view.php?id=34031 for my boss) which has the 
SetLength intrinsic return aligned memory. We need this for the Metal framework 
which requires all vertex buffer memory to aligned on 4k boundaries so we can’t 
use dynamic arrays in their current form (see the bug report for example code).

I’ve looked at the dynamic array implementation (dynarr.inc) and it appears 
that I could over allocate and extend the header (tdynarray) to include an 
extra field which stores the amount of padding until the actual array elements 
start (which is aligned). It would complicit the code to some extent however 
because the current design relies on lots of pointer math.

Is this ok that I add this? Marco said in the comments there was a need so I 
assume this is a go but I wanted to ask first.

Regards,
Ryan Joseph

___
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel