C
Cameron McBride
------=_Part_9477_9412626.1139692302456
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
I'm trying to make the fast extensions to NArray, yet still preserve
the general nature of methods (i.e. works on all NArray types). As an
example, I'll show benchmarks of a simple weighted mean:
Benchmarking based:
num_runs =3D 1000
data_size =3D 100000
user system total real
NArray_rb 3.150000 0.660000 3.810000 ( 3.803652)
NArray_mod 3.930000 0.020000 3.950000 ( 3.949027)
NArray_dbl 1.040000 0.000000 1.040000 ( 1.039897)
GSL 1.670000 0.000000 1.670000 ( 1.665538)
(sorry, Gmail messed with the formating on paste)
I did the quick NArray_dbl hack, which is fast but explicitly casts to
'double', so it's not general. When I generalized it using some
internal SetFuncs of NArray, the result is slower than a ruby version
that does a double loop (two #sum calls).
What am I missing? As a success meter, I'd like it to be at least as
fast as GSL libs.
(benchmark and code attached. additionally uses inline and rb-gsl)
Thanks!
Cameron
------=_Part_9477_9412626.1139692302456
Content-Type: application/octet-stream; name=bench_wmean.rb
Content-Transfer-Encoding: 7bit
X-Attachment-Id: f_ejkf4aha
Content-Disposition: attachment; filename="bench_wmean.rb"
#!/usr/bin/env ruby
require 'benchmark'
include Benchmark
require 'gsl'
require 'na_wmean.rb'
n = 1_000
data_size = 100_000
x = NArray.float(data_size).random!
w = NArray.float(data_size).random!
gx = x.to_gv
gw = w.to_gv
def wmean_orig(xt,wt)
(xt * wt).sum / wt.sum
end
puts "Benchmarking based: "
puts " num_runs = #{n}"
puts " data_size = #{data_size}"
bmbm(12) do |be|
be.report("NArray_rb") { n.times { m = wmean_orig(x,w)} }
be.report("NArray_mod") { n.times { m = x.wmean(w)} }
be.report("NArray_dbl") { n.times { m = x.wmean_dbl(w)} }
be.report("GSL") { n.times { m = gx.wmean(gw)} }
end
------=_Part_9477_9412626.1139692302456
Content-Type: application/octet-stream; name=na_wmean.rb
Content-Transfer-Encoding: 7bit
X-Attachment-Id: f_ejkf4ll0
Content-Disposition: attachment; filename="na_wmean.rb"
#!/usr/bin/env ruby
require 'rubygems'
require 'narray'
require 'inline'
class NArray
inline do |builder|
builder.add_compile_flags %q(-I /export/home/cameron/sys/narray-0.5.8/)
builder.include '"narray.h"'
builder.include '"narray_local.h"' # few local things used in linspace
builder.c_raw <<-'END_CODE'
VALUE
wmean_dbl(int argc, VALUE *argv, VALUE self) {
int i;
struct NARRAY *nv, *nw;
double p_sum = 0.0, w_sum = 0.0;
GetNArray(self, nv);
GetNArray(argv[0], nw);
if(nv->total != nw->total)
rb_raise( rb_eArgError, "Vector and weight must be same size!" );
for(i=0 ; i < nv->total ; i++) {
p_sum += ((double *)nw->ptr) * ((double *)nv->ptr);
w_sum += ((double *)nw->ptr);
}
return rb_float_new( p_sum / w_sum);
}
END_CODE
builder.c_raw <<-'END_CODE'
VALUE
wmean(int argc, VALUE *argv, VALUE self) {
int i,sv,sw;
struct NARRAY *nv, *nw;
double wt,val;
double p_sum = 0.0, w_sum = 0.0;
char *v,*w;
void (*na_getv)();
void (*na_getw)();
GetNArray(self, nv);
GetNArray(argv[0], nw);
if(nv->total != nw->total)
rb_raise( rb_eArgError, "Vector and weight must be same size!" );
na_getv = SetFuncs[NA_DFLOAT][nv->type];
na_getw = SetFuncs[NA_DFLOAT][nw->type];
sv = na_sizeof[nv->type];
sw = na_sizeof[nw->type];
v = nv->ptr;
w = nw->ptr;
for(i=0 ; i < nv->total ; i++) {
(*na_getv)( 1, &val, 0, v, 0 );
(*na_getw)( 1, &wt, 0, w, 0 );
v += sv;
w += sw;
p_sum += (wt) * (val);
w_sum += (wt);
}
return rb_float_new( p_sum / w_sum);
}
END_CODE
end
end
------=_Part_9477_9412626.1139692302456--
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Disposition: inline
I'm trying to make the fast extensions to NArray, yet still preserve
the general nature of methods (i.e. works on all NArray types). As an
example, I'll show benchmarks of a simple weighted mean:
Benchmarking based:
num_runs =3D 1000
data_size =3D 100000
user system total real
NArray_rb 3.150000 0.660000 3.810000 ( 3.803652)
NArray_mod 3.930000 0.020000 3.950000 ( 3.949027)
NArray_dbl 1.040000 0.000000 1.040000 ( 1.039897)
GSL 1.670000 0.000000 1.670000 ( 1.665538)
(sorry, Gmail messed with the formating on paste)
I did the quick NArray_dbl hack, which is fast but explicitly casts to
'double', so it's not general. When I generalized it using some
internal SetFuncs of NArray, the result is slower than a ruby version
that does a double loop (two #sum calls).
What am I missing? As a success meter, I'd like it to be at least as
fast as GSL libs.
(benchmark and code attached. additionally uses inline and rb-gsl)
Thanks!
Cameron
------=_Part_9477_9412626.1139692302456
Content-Type: application/octet-stream; name=bench_wmean.rb
Content-Transfer-Encoding: 7bit
X-Attachment-Id: f_ejkf4aha
Content-Disposition: attachment; filename="bench_wmean.rb"
#!/usr/bin/env ruby
require 'benchmark'
include Benchmark
require 'gsl'
require 'na_wmean.rb'
n = 1_000
data_size = 100_000
x = NArray.float(data_size).random!
w = NArray.float(data_size).random!
gx = x.to_gv
gw = w.to_gv
def wmean_orig(xt,wt)
(xt * wt).sum / wt.sum
end
puts "Benchmarking based: "
puts " num_runs = #{n}"
puts " data_size = #{data_size}"
bmbm(12) do |be|
be.report("NArray_rb") { n.times { m = wmean_orig(x,w)} }
be.report("NArray_mod") { n.times { m = x.wmean(w)} }
be.report("NArray_dbl") { n.times { m = x.wmean_dbl(w)} }
be.report("GSL") { n.times { m = gx.wmean(gw)} }
end
------=_Part_9477_9412626.1139692302456
Content-Type: application/octet-stream; name=na_wmean.rb
Content-Transfer-Encoding: 7bit
X-Attachment-Id: f_ejkf4ll0
Content-Disposition: attachment; filename="na_wmean.rb"
#!/usr/bin/env ruby
require 'rubygems'
require 'narray'
require 'inline'
class NArray
inline do |builder|
builder.add_compile_flags %q(-I /export/home/cameron/sys/narray-0.5.8/)
builder.include '"narray.h"'
builder.include '"narray_local.h"' # few local things used in linspace
builder.c_raw <<-'END_CODE'
VALUE
wmean_dbl(int argc, VALUE *argv, VALUE self) {
int i;
struct NARRAY *nv, *nw;
double p_sum = 0.0, w_sum = 0.0;
GetNArray(self, nv);
GetNArray(argv[0], nw);
if(nv->total != nw->total)
rb_raise( rb_eArgError, "Vector and weight must be same size!" );
for(i=0 ; i < nv->total ; i++) {
p_sum += ((double *)nw->ptr) * ((double *)nv->ptr);
w_sum += ((double *)nw->ptr);
}
return rb_float_new( p_sum / w_sum);
}
END_CODE
builder.c_raw <<-'END_CODE'
VALUE
wmean(int argc, VALUE *argv, VALUE self) {
int i,sv,sw;
struct NARRAY *nv, *nw;
double wt,val;
double p_sum = 0.0, w_sum = 0.0;
char *v,*w;
void (*na_getv)();
void (*na_getw)();
GetNArray(self, nv);
GetNArray(argv[0], nw);
if(nv->total != nw->total)
rb_raise( rb_eArgError, "Vector and weight must be same size!" );
na_getv = SetFuncs[NA_DFLOAT][nv->type];
na_getw = SetFuncs[NA_DFLOAT][nw->type];
sv = na_sizeof[nv->type];
sw = na_sizeof[nw->type];
v = nv->ptr;
w = nw->ptr;
for(i=0 ; i < nv->total ; i++) {
(*na_getv)( 1, &val, 0, v, 0 );
(*na_getw)( 1, &wt, 0, w, 0 );
v += sv;
w += sw;
p_sum += (wt) * (val);
w_sum += (wt);
}
return rb_float_new( p_sum / w_sum);
}
END_CODE
end
end
------=_Part_9477_9412626.1139692302456--