I just wanted to let everyone know that the “next” branch now contains
the VOLK library.

For those of you who did not hear me talk about it at the SDR
conference last week, I wrote up a very quick and dirty intro note

I’ll be providing much more detail about it in the coming weeks.


Hey Tom,

Great work implementing the libvolk. I had a chance to take a peek at
the implementation, so now I have constructive criticism. :slight_smile:

I see that the various vector functions are all implemented in headers,
and at compile time, a python application generates them into the table
look-up-code. I would like to purpose an alternative for registering the
functions that is a little more modular.

Ideally, the functions should register themselves automatically into the
volk registry (and this would happen dynamically at runtime). That way,
you can put the implementations into their own respective c++ files that
are fully encapsulated and just list them into the library sources. In
addition, users of gnuradio could register their own vectorized
implementations into volk for out-of-tree private projects. And, this
may make it easier to integrate liborc.

So let me go about the primitives

– registering a function

//vectorized adder.cc

static void add_ff_v(data in0, data in1, data out){
//impl here

volk_register_fcn(, , &add_ff_v);

…and so on

Now, the static block is a macro that creates and instantiates an object
for the purpose of static initialization. Example in UHD:

– The function registry

The function registry is essentially a dictionary mapping tags to a
dictionary of architectures to function pointers. Whenever volk_register
is called, its adds an entry into the registry.

Now there should also be a function to access the registry.
volk_get_fcn() would grab a pointer to the most efficient
implementation, and then be cast from void * to whatever is useful.

This isnt the same as just calling a function from a header. Since
volk_get_fcn would have overhead, it should not be called in the fast
path, but once at initialization int he block’s constructor to extract
the function pointer.

As an alternative to fetching the function pointer, you might instead
fetch a opaque table object that has the reference to a set of
vectorized functions. It may be useful to select among functions at
runtime based on alignment of the input data. I think liborc does this.

– Tag names

This goes back to the same debates about tag names for the tags
streaming interface stuff. In any case, it just has to be something
identifiable. It could be enums. I would just make it strings (since its
out of the fast path), where a set of functions and their usage
implementation agrees on a string name. A string would be an identifying
signature like add_v_f32_…

Let me know what you think,