If optlink links the code successfully, I don't understand what the problem
is. Optlink is far and away the best linker ever written.

I agree, but it fails as soon as the data declared at file scope exceed 40 MB
total.
As you maybe remember, we had this discussion a few months ago: DMC produces
very fast executables, better then any competitor. However, if I use dynamic
memory allocation, speed degrades by 30 percent. Still better than other
compilers using dynamic allocation, but worse than other compiler on huge static
data.
I'm trying to find a way out of the problem.
BTW. If I declare the big arrays 'static', Blinker does not complain anymore on
the .obj, but has problems with SNN.LIB. The same happens with Borland Tlink.
Any clue?
Federico

I meant, the messages the linker gives you. You give a report for all the other
linkers I can not help you with.

It seems to me like you have to throw an option for blinker to prevent it from
capitalizing the function names, that might fix one problem.

Thanks Jan, you are obviously write (and I'm a stupid :-( ). Your message
prompted me to better study the horrible on line documentation of Blinker
DEMO version, and I happened to write the correct script and definiton files
to produce a Win32 executables, just to discover that: [ ... ]

Yes. I'm not used to hide information to people helping me... ;-)
Walter said it is a problem in OPTLINK he cannot fix.
BTW, I'm running WinME, but I had the same problem with different versions and
on different systems.
Federico

1) Record type BC is a COMDAT record - perfectly valid. Bug in Alink.
2) These externs should be defined in whatever operating system .lib file
you're linking with - not a problem with SNN.LIB.
3) Identifying the problem as being with SNN.OBJ (when the name of the file
is SNN.LIB) indicates a bug in ilink32, not SNN.
4) Access violations when ilink32 is run is a bug in the linker, not SNN.
"Federico" <Federico_member pathlink.com> wrote in message
news:aic9qt$d1o$1 digitaldaemon.com...

BTW. If I declare the big arrays 'static', Blinker does not complain anymore
on the .obj, but has problems with SNN.LIB. The same happens with Borland
Tlink.

I never said "SNN.LIB causes problems".
Federico
In article <aicch8$ggd$1 digitaldaemon.com>, Walter says...

1) Record type BC is a COMDAT record - perfectly valid. Bug in Alink.
2) These externs should be defined in whatever operating system .lib file
you're linking with - not a problem with SNN.LIB.
3) Identifying the problem as being with SNN.OBJ (when the name of the file
is SNN.LIB) indicates a bug in ilink32, not SNN.
4) Access violations when ilink32 is run is a bug in the linker, not SNN.

Thanks to everyone who replied. Now that I solved the problem and I'm happy,I
have to make two comments:
1) the C standard and DMC docs state no limit on statically allocated areas.
I know form past interactiosn that the (wonderful!) linker is not in Walter's
control, but that problem is not nice at all;
2) before solving the problem, I anyhow ordered the DM CD: it's a wonderful
product, I love it more than I loved Symantec C++ in the past, it's worth
really more than 25 bucks!
Federico

I agree, but it fails as soon as the data declared at file scope exceed 40 MB
total.
As you maybe remember, we had this discussion a few months ago: DMC produces
very fast executables, better then any competitor. However, if I use dynamic
memory allocation, speed degrades by 30 percent. Still better than other
compilers using dynamic allocation, but worse than other compiler on huge
static
data.
I'm trying to find a way out of the problem.

Why not allocating a big buffer on startup? It shouldn't make much
difference in access time if you change
char big_buffer[big_size];
// doing something with big_buffer
to
char *big_buffer = new char[big_size]; // or malloc
// doing somthing with big_buffer
There is only one dynamic memory allocation in this case. The rest is
nearly the same. Ok, the static buffer can be accessed with immediate
addresses where the dynamic buffer pointer must first be loaded to a
register and offset addressed. But I would expect that this isn't a big
performance degradation.
- Heinz

Why not allocating a big buffer on startup? It shouldn't make much
difference in access time if you change

Sorry, it does.
I was able to reduce the problem to a simple and stupid matrix multiplication
of two NxN matrices into a third one (the original code is different and
much more sophisticated, but exhibits the very same pathology).
Please, look at those measures (dynamic means that memory is allocated
once at the very beginning):
N Allocation DMC 8.28 BC++ 5.5
500 static 2.45 s 2.70 s
500 dynamic 3.17 s 3.67 s
2000 static link failed! 141.13 s
2000 dynamic 166.31 s 196.81 s
Not only is DMC better than other compiler in most respects (support of
accurate floating point computation is wonderful), it produces faster
executables too.
However, performance degradations resulting from the switch from static
to dynamic memory allocation are significant (actually deadly for my
application).

nearly the same. Ok, the static buffer can be accessed with immediate
addresses where the dynamic buffer pointer must first be loaded to a
register and offset addressed. But I would expect that this isn't a big
performance degradation.

No, this is not a problem. There is not much difference between accessing
memory locations in an array and accessing memory locations in a malloc'ed
area, not with a barely decent optimizing compiler. I can prove that easily,
it is even more evident on RISC architectures and the progressive
RISC-ification of x86 processors made this true for them as well.
I had not time to look in detail to DMC generated assembler, but the one for
the computational core is much more verbose and lenghty for the dinamic
allocation version than for the static one.
This usually comes from the optimizer being more aggressive with static data,
as it can more easily check at compile time for aliasing problems, something
cannot be done easily for dynamically allocated areas and pointers to them.
With FORTRAN 77, which always assume no aliasing (if you don't use EQUIVALENCE,
of course), there is no difference if you pass to a subroutine a static data
area or a malloc'ed one. In FORTRAN 9X, which supports pointers, aliasing can
be an issue, and performance can degrades.
In FORTRAN 9X you can fine control the effect using the TARGET attribute (if
the compiler takes advantage of the information), C99 introduced the restrict
keyword with similar purposes, and using it can pay a lot with some compilers.
To my surprise, using __restrict with DMC had no effect.
Federico

Why not allocating a big buffer on startup? It shouldn't make much
difference in access time if you change

Sorry, it does.
I was able to reduce the problem to a simple and stupid matrix multiplication
of two NxN matrices into a third one (the original code is different and
much more sophisticated, but exhibits the very same pathology).

Could you give an example in 'code' of what you are doing and how static v.s.
dynamic makes such a difference?
Jan

Why not allocating a big buffer on startup? It shouldn't make much
difference in access time if you change

Sorry, it does.
I was able to reduce the problem to a simple and stupid matrix multiplication
of two NxN matrices into a third one (the original code is different and
much more sophisticated, but exhibits the very same pathology).

Do you do the matrix multiply in a function taking the matrices as
'pointer to double' parameters like
void MatrixMul(int N, double *A, double *B, double *C)
{ // multiply NxN matrix A*B resulting in C
}
and call this with static allocated matrix in one case and dynamic one
in the other case? This should not result in different performance as
the generated code for MatrixMul would be the same.
What would make a difference is simulating a 2D array with pointers as
in
double **A = new double*[N];
for(int i=0; i<N; ++i) A[i] = new double[N];
// same for B and C
and writing MatrixMul as
void MatrixMul(int N, double **A, double **B, double **C)
{ // do the multiply
}
This would indeed involve a overhead.
Another point could be different alignment of static array and dynamic
allocated array. We had this discussion in the group that 8-byte aligned
doubles are faster than 4-byte aligned doubles.

I had not time to look in detail to DMC generated assembler, but the one for
the computational core is much more verbose and lenghty for the dinamic
allocation version than for the static one.
This usually comes from the optimizer being more aggressive with static data,
as it can more easily check at compile time for aliasing problems, something
cannot be done easily for dynamically allocated areas and pointers to them.

IMO this can only happen when the routines directly access the global
static buffer and not taking the arguments as parameters.
But, as Jan said, a small example code for static and dynamic version
may help to clarify where the difference is.
- Heinz

Do you do the matrix multiply in a function taking the matrices as
'pointer to double' parameters like
void MatrixMul(int N, double *A, double *B, double *C)

Look at the codes I sent, please.

What would make a difference is simulating a 2D array with pointers as
in
double **A = new double*[N];

I'm not so stupid or ignorant to do that.

Another point could be different alignment of static array and dynamic
allocated array. We had this discussion in the group that 8-byte aligned
doubles are faster than 4-byte aligned doubles.

That's obvious stuff I dind't mentioned, I'm using floats.

IMO this can only happen when the routines directly access the global
static buffer and not taking the arguments as parameters.

This is the same conclusion I came to looking at assembly language compiler
output.
However, this is only true for DMC, try with BC++, or a compiler for RISC
architectures anf you'll find that this makes no difference (as it should be...)
Federico