![]() |
Blitz Support : |
From: Peter Kümmel (syntheticpp_at_[hidden])
Date: 2005-06-18 13:33:37
Julian Cummings wrote:
> No. But you can look at the assembly code (yuck!) or just try an
> experiment comparing with some hand-coded C with for loops.
That's hard. :(
> Hmmm... this started from defining a struct that had a scalar member
> function and then converting that member function into a member function
> that would operate on an Array. I guess my question would be how would
> the original scalar function have known anything about Array indices. I
> think that by design, these are not functions that operate on Array
> indices. Perhaps your original scalar function looks like this:
>
> double f(double x, int i, int j) { return x*exp(sqrt(i*i+j*j)); }
>
> There is no nifty macro for converting this sort of function into
> something that takes an Array and assumes i and j to be the indices.
> But if the function is so simple, why not just write it out with blitz
> tensor notation and Arrays?
>
>
>>Is the usage of the indices the best way to implement such
>>calculations? I've written some benchmark code to compare with
>>C-code and C is in all cases the fasted one.
>>
>
>
> Really? I just tried an example and got exactly the same performance
> from blitz and C. I am attaching my example codes. I compiled them
> with gcc 4.0.0 and full optimization (-O3) and each one took about 10
> seconds to run on my Opteron. The example is taken from your original
> example code.
Your are right, here the performance are also nearly identical.
I forgot to mention, that I've done my tests on arrays with complex numbers.
I've found that the main reason for slowing down blitz is the absence of
a constructor which takes indices, e.g.:
firstIndex x;
secondIndex y;
A = A * exp( complex<double>(x,y) );
At least, I've found no way to compile this code.
Introducing a helperfunction does the job:
complex<double> cplx(double re, double im){
return complex<double>(re,im);
}
But if I build more complex functions like
complex<double> cplx3(double re, double im, double d){...}
the compiler can't convert the ET type:
double a,b;
firstIndex x;
A = A * exp(cplx3(a,b,sqrt(x));
gcc:
cannot convert `blitz::_bz_ArrayExpr<blitz::
_bz_ArrayExprUnaryOp<blitz::IndexPlaceholder<0>, blitz::Fn_sqrt<int> > >'
to `double' for argument `3' to
`std::complex<double> cplx3(double, double, double)'
(I've here a BZ_DEFINE_TERNARY_FUNC_RET macro which
I could submit if you are intested)
> The blitz Arrays have iterators which are now more or less STL
> compliant. This allows you to write a generic loop over Array elements
> and do whatever calculation you want to each element. The iterator type
> also has a special position() member that returns the current Array
> indices in a TinyVector of ints. So you could say
>
> #define DIM 2
> Array<double,DIM>::iterator it, iend = A.end();
> for (it = A.begin(); it != iend; ++it) {
> TinyVector<int,DIM> pos = it.position();
> *it = *it * exp(sqrt(dot(pos,pos)));
> }
So I must do the loop by hand, hoped that there is also
a blitz like solution.
Thank you very much for your time and consideration!
Peter