Re: Re[2]: [sqlite] Unaligned access in SQLite on Itanium

2006-03-27 Thread Alexei Alexandrov
>
> Unless the on disk format is carried over into memory, there's no
> reason not to use a structure alignment which prevents unaligned
> access.
>
> I'm a little surprised your compiler hadn't already padded the struct
> out to proper alignment when you built SQLite.
>

Sorry, I'm a little bit lost here. Maybe I mis-explained something -
maybe due to my non-native English. Sorry for that. Let's re-iterate
through my problem once again.

My compiler does have right padding. By default, almost all compilers
will align structure members on natural alignment boundary, which
means align a member on the offset which is a multiple of the member
data size.

In my case it is array of chars that has got mis-aligned. To be
precise, it is aligned just right to store 1, 2, 4, 8 size types
there, but it is not aligned properly for 16-byte long double. For
this case, #pragma pack, which is more or less portable (I really like
this 'more or less portable' - crazy world, you've gone too far...),
won't work because it allows only to pack - that is, to lower
alignment boundaries - it is used when you need to pack structures for
network transfer, for example. And in fact, #pragma pack can only make
hardware alignment issues only worse.

So the only (known so far) portable way to fix the problem is to union
the problematic array with long double variable to get it aligned
properly - on 16-bytes boundary. On GCC we could also use

__attribute__ ((aligned (16)))

but it is not portable.

Please don't hesitate to ask for clarifications if something is not
clear here - I really want to follow it up ASAP.

--
Alexei Alexandrov


Re[2]: [sqlite] Unaligned access in SQLite on Itanium

2006-03-27 Thread Teg
Hello Jay,



Monday, March 27, 2006, 12:25:36 PM, you wrote:

JS> On 3/27/06, Alexei Alexandrov <[EMAIL PROTECTED]> wrote:
>> >
>> > Isn't this eliminated with the proper compile settings for data packing?
>> > There should be a compile option for sometihng like 'align data on N
>> > byte boundaries'
>> >
>>
>> Even if that is possible, I don't want to say to compiler "Please
>> align everything on 16 bytes" because this will lead to huge memory
>> footprint overhead - every element - even 1 byte-long will take 16
>> bytes in memory. This is not an option.

JS> The compiler I used was smarter than that in the 1980's...

I agree. Typically it's just structure alignments so, for instance if
you had a char followed by a short in the struct, it would get padded
out to 16 bytes but, it wouldn't pad unless it had too. 15 chars
for instance would have a 1 byte pad. Structs HAVE to be aligned in
order to prevent unaligned access unless you're working with something
byte centric like a net protocol which requires you to work with no or
smaller alignments. The native alignment for my windows apps is 8
bytes. When I tried Visual Studio 2005, the default alignment was 16
bytes (which caused me some real problems till I figured it out).

Unless the on disk format is carried over into memory, there's no
reason not to use a structure alignment which prevents unaligned
access.

I'm a little surprised your compiler hadn't already padded the struct
out to proper alignment when you built SQLite.







-- 
Best regards,
 Tegmailto:[EMAIL PROTECTED]



Re: [sqlite] Unaligned access in SQLite on Itanium

2006-03-27 Thread Jay Sprenkle
On 3/27/06, Alexei Alexandrov <[EMAIL PROTECTED]> wrote:
> >
> > Isn't this eliminated with the proper compile settings for data packing?
> > There should be a compile option for sometihng like 'align data on N
> > byte boundaries'
> >
>
> Even if that is possible, I don't want to say to compiler "Please
> align everything on 16 bytes" because this will lead to huge memory
> footprint overhead - every element - even 1 byte-long will take 16
> bytes in memory. This is not an option.

The compiler I used was smarter than that in the 1980's...


Re: [sqlite] Unaligned access in SQLite on Itanium

2006-03-27 Thread Alexei Alexandrov
>
> Isn't this eliminated with the proper compile settings for data packing?
> There should be a compile option for sometihng like 'align data on N
> byte boundaries'
>

Even if that is possible, I don't want to say to compiler "Please
align everything on 16 bytes" because this will lead to huge memory
footprint overhead - every element - even 1 byte-long will take 16
bytes in memory. This is not an option.

--
Alexei Alexandrov


Re: [sqlite] Unaligned access in SQLite on Itanium

2006-03-27 Thread Jay Sprenkle
On 3/25/06, Alexei Alexandrov <[EMAIL PROTECTED]> wrote:
> Hi,
>
> I don't know whether it's been already reported or not, so anyway.
> There are places in SQLite where unaligned access exception is
> generated on Itanium. The unaligned access means that someone tries to
> read or write memory crossing 8-bytes boundary. Usually this occur as
> a result of pointers casting.

Isn't this eliminated with the proper compile settings for data packing?
There should be a compile option for sometihng like 'align data on N
byte boundaries'


Re: [sqlite] Unaligned access in SQLite on Itanium

2006-03-27 Thread drh
"Alexei Alexandrov" <[EMAIL PROTECTED]> wrote:
> >
> > Well, it's supported by most compilers today, but I try to avoid
> > anonymous unions in C code as well. They are fairly standard for C++,
> > but not for C. But the approach seems fine to me - the alignment will
> > be forced in this case.
> >
> 
> Just to make it clear: can I expect this fix in the next SQLite
> release? Should I submit a ticket for this? I will provide Linux
> ia64/x86_64 testing from my side.
> 

Submit a ticket or it will likely fall through the cracks.
--
D. Richard Hipp   <[EMAIL PROTECTED]>



Re: [sqlite] Unaligned access in SQLite on Itanium

2006-03-26 Thread Alexei Alexandrov
>
> Well, it's supported by most compilers today, but I try to avoid
> anonymous unions in C code as well. They are fairly standard for C++,
> but not for C. But the approach seems fine to me - the alignment will
> be forced in this case.
>

Just to make it clear: can I expect this fix in the next SQLite
release? Should I submit a ticket for this? I will provide Linux
ia64/x86_64 testing from my side.

--
Alexei Alexandrov


Re: [sqlite] Unaligned access in SQLite on Itanium

2006-03-25 Thread Alexei Alexandrov
> Perhaps a better fix is this:
>
>  struct Mem {
>i64 i;
>double r;
>char *z;
>int n;
>u16 flags;
>u8  type;
>u8  enc;
>void (*xDel)(void *);
>union {
>  long double notUsed1;
>  char zShort[NBFS];
>};
>  };
>
> The compiler would then (hopefully) insert an appropriate
> amount of padding prior to zShort so that it had the same
> alignment restructions as a long double.
>
> This approach uses an anonymous union, which I confess is
> a C construct that I have never in 22 years of C programming
> had the occasion to employ.  It seems to work well enough
> using gcc 3.3.4.  But down in my gut I have this nagging
> fealing that it will likely break on some compilers.
>

Well, it's supported by most compilers today, but I try to avoid
anonymous unions in C code as well. They are fairly standard for C++,
but not for C. But the approach seems fine to me - the alignment will
be forced in this case.


Re: [sqlite] Unaligned access in SQLite on Itanium

2006-03-25 Thread drh
"Alexei Alexandrov" <[EMAIL PROTECTED]> wrote:
> >
> > Perhaps the following definition of Mem would work better:
> >
> >  struct Mem {
> >u16 flags;
> >u8  type;
> >u8  enc;
> >char *z;
> >int n;
> >i64 i;
> >double r;
> >char zShort[NBFS];
> >void (*xDel)(void *);
> >  };
> >
> 
> Not exactly, since 'int' is still 4 bytes on Linux ia64. long/size_t
> is 8 bytes. In fact, I think that the rightest thing here would be to
> put zShort at the beginning of the structure, because in this case it
> would get the same alignment as returned from malloc and the rest of
> fields are strictly typed so that they are aligned by compiler
> properly.
> 
> But when I try to put zShort at the beginning, some strange thing
> happens - SQLite doesn't like it. I start SQLite shell, and it says
> immediately (or when I create a simple table):
> 

Come to think of it, I there are some places in the code that
assume that zShort[] is at the end of the structure.  There 
are places that memcpy() the first part of the structure and
ignore zShort[].  So moving zShort[] to any other place in the
structure will not work unless those places are changed.  And
those places are there for efficiency reasons so I am reluctant
to change them.

Perhaps a better fix is this:

  struct Mem {
i64 i; 
double r;  
char *z;   
int n; 
u16 flags; 
u8  type;  
u8  enc;   
void (*xDel)(void *);
union {
  long double notUsed1;
  char zShort[NBFS];
};
  };

The compiler would then (hopefully) insert an appropriate
amount of padding prior to zShort so that it had the same 
alignment restructions as a long double.

This approach uses an anonymous union, which I confess is
a C construct that I have never in 22 years of C programming
had the occasion to employ.  It seems to work well enough
using gcc 3.3.4.  But down in my gut I have this nagging
fealing that it will likely break on some compilers.

--
D. Richard Hipp   <[EMAIL PROTECTED]>



Re: [sqlite] Unaligned access in SQLite on Itanium

2006-03-25 Thread Alexei Alexandrov
>
> The Mem structure does not appear on disk or in any API (except
> as the opaque structure pointer sqlite3_value*) so it can be
> revised as needed to force 16-byte alignment.  Perhaps
> the following definition of Mem would work better:
>
>  struct Mem {
>u16 flags;
>u8  type;
>u8  enc;
>char *z;
>int n;
>i64 i;
>double r;
>char zShort[NBFS];
>void (*xDel)(void *);
>  };
>
> Assuming the entire structure is 16-byte aligned and pointers
> and integers are all 8-bytes and 8-byte aligned, then there
> would be 4 bytes of padding between Mem.enc and Mem.z.  This
> would result in zShort appearing on a 16-byte boundary, would
> it not?
>

Not exactly, since 'int' is still 4 bytes on Linux ia64. long/size_t
is 8 bytes. In fact, I think that the rightest thing here would be to
put zShort at the beginning of the structure, because in this case it
would get the same alignment as returned from malloc and the rest of
fields are strictly typed so that they are aligned by compiler
properly.

But when I try to put zShort at the beginning, some strange thing
happens - SQLite doesn't like it. I start SQLite shell, and it says
immediately (or when I create a simple table):

D:\src\3rd-parties\sqlitecomp\bin\windows-x32>sqlite3-test.exe test.db
SQL error: malformed database schema
Can't prepare statement: no such table: test

Reproduced on Windows x86 and Linux ia64.

--
Alexei Alexandrov


Re: [sqlite] Unaligned access in SQLite on Itanium

2006-03-25 Thread drh
"Alexei Alexandrov" <[EMAIL PROTECTED]> wrote:
> As far as I understand, this fix will take the problem away only
> because SumCtx is bigger now. But the problem with
> sqlite3_aggregate_context will remain: the pointer returned will not
> be aligned properly if the size of the context is less or equal 32
> bytes. Am I correct?
> 

The context should be 8-byte aligned regardless.  And after
check-in [3084] there are no long doubles stored in the context
so 8-byte alignment is sufficient - provided of course that you
do not implement your own private aggregate functions that
require a 16-byte aligned context.

The Mem structure does not appear on disk or in any API (except
as the opaque structure pointer sqlite3_value*) so it can be 
revised as needed to force 16-byte alignment.  Perhaps 
the following definition of Mem would work better:

  struct Mem {
u16 flags;   
u8  type;
u8  enc; 
char *z; 
int n;   
i64 i;   
double r;
char zShort[NBFS];
void (*xDel)(void *);
  };

Assuming the entire structure is 16-byte aligned and pointers
and integers are all 8-bytes and 8-byte aligned, then there
would be 4 bytes of padding between Mem.enc and Mem.z.  This
would result in zShort appearing on a 16-byte boundary, would
it not?

--
D. Richard Hipp   <[EMAIL PROTECTED]>



Re: [sqlite] Unaligned access in SQLite on Itanium

2006-03-25 Thread Alexei Alexandrov
As far as I understand, this fix will take the problem away only
because SumCtx is bigger now. But the problem with
sqlite3_aggregate_context will remain: the pointer returned will not
be aligned properly if the size of the context is less or equal 32
bytes. Am I correct?

On 3/25/06, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
> "Alexei Alexandrov" <[EMAIL PROTECTED]> wrote:
> > Hi,
> >
> > I don't know whether it's been already reported or not, so anyway.
> > There are places in SQLite where unaligned access exception is
> > generated on Itanium. The unaligned access means that someone tries to
> > read or write memory crossing 8-bytes boundary. Usually this occur as
> > a result of pointers casting.
> >
> > I investigated it a little bit and found that the reason is this line
> > in func.c file:
> >
> >   p->sum += sqlite3_value_int64(argv[0]);
> >
>
> This was fixed by check-in [3084] which occurred a few
> hours after 3.3.4 was released (2006-Feb-11).
> http://www.sqlite.org/cvstrac/chngview?cn=3084
> --
> D. Richard Hipp   <[EMAIL PROTECTED]>
>
>


--
Alexei Alexandrov


Re: [sqlite] Unaligned access in SQLite on Itanium

2006-03-25 Thread drh
"Alexei Alexandrov" <[EMAIL PROTECTED]> wrote:
> Hi,
> 
> I don't know whether it's been already reported or not, so anyway.
> There are places in SQLite where unaligned access exception is
> generated on Itanium. The unaligned access means that someone tries to
> read or write memory crossing 8-bytes boundary. Usually this occur as
> a result of pointers casting.
> 
> I investigated it a little bit and found that the reason is this line
> in func.c file:
> 
>   p->sum += sqlite3_value_int64(argv[0]);
> 

This was fixed by check-in [3084] which occurred a few
hours after 3.3.4 was released (2006-Feb-11).
http://www.sqlite.org/cvstrac/chngview?cn=3084
--
D. Richard Hipp   <[EMAIL PROTECTED]>



[sqlite] Unaligned access in SQLite on Itanium

2006-03-25 Thread Alexei Alexandrov
Hi,

I don't know whether it's been already reported or not, so anyway.
There are places in SQLite where unaligned access exception is
generated on Itanium. The unaligned access means that someone tries to
read or write memory crossing 8-bytes boundary. Usually this occur as
a result of pointers casting.

I investigated it a little bit and found that the reason is this line
in func.c file:

  p->sum += sqlite3_value_int64(argv[0]);

It is a part of sumStep function. p->sum is long double, that is 16
bytes size. It means that it must be aligned on 16 bytes boundary, but
it is 0x60094248 in my case. The reason it is not aligned is
that address returned by sqlite3_aggregate_context is not aligned on
16 bytes boundary which is a must for ia64 systems and which is the
alignment of malloc returned pointers.

So the reason comes to Mem structure and I can see that zShort member
is not forced to be aligned on 16 bytes and in fact it is aligned on 8
bytes.

This is where I got stuck because I don't know whether Mem structure
is on-disk structure or not. Is it OK to change it?

P.S. To catch the unaligned access on Itanium, the easiest way is to say

prctl --unaligned=signal
ulimit -c unlimited

After that unaligned access will cause SIGBUS and core dump will be generated.

P.P.S. Unaligned access can lead to serious performance degradations
and on some OSes (HP-UX) there isn't default unaligned access handler
so it will just crash.

--
Alexei Alexandrov