[vsipl++] [patch] functional code for SPE-based vector multiply
Stefan Seefeld
stefan at codesourcery.com
Wed Jan 3 02:33:22 UTC 2007
Don McCoy wrote:
> This patch builds on the dispatch added by Stefan. Specifically, it:
>
> * Encapsulates the initialization and shutdown code for setting up
> the SPE
> * Separates the sending of the data from the command to actually do
> the multiplication
> * Actually multiplies the vectors (not using intrinsics, but this is
> a simple change)
Very nice !
Here is one high-level comment, as well as (as usual ;-) ) some nit-picking:
> +Elementwise_vmul::Elementwise_vmul()
> +{
> + gid_ = spe_create_group(SCHED_OTHER, 0, 1);
> + if (gid_ == NULL)
> + {
> + std::cerr << "Failed spe_create_group(errno=" << errno << ")" << std::endl;
> + return;
> + }
We shouldn't write to std::cerr here. Instead, we should define some exception
type that would be thrown in case of error.
[...]
> +
> +static Elementwise_vmul elementwise_vmul;
The Elementwise_vmul object should be allocated from inside the global vsipl object.
This also gives us the opportunity to handle Cell-specific command-line options, such
as define the concurrency level, or different dispatch strategies.
However, doing that requires the type to become truely generic, such that...
> +template <typename T>
> +void Elementwise_vmul::apply(T const *A, T const *B, T *R, length_type len)
...this becomes a generic call, taking some 'op-code' parameter that indicates
what operation to perform.
> + volatile command_block cb __attribute__ ((aligned (128)));
> + volatile data_block db[3] __attribute__ ((aligned (128)));
> +
> + speid_t speid = elementwise_vmul.speid_;
> +
> + // pass data blocks to SPE
> + {
> + db[0].element_size = sizeof(float);
Does this mean you assume the template parameter T is now float ?
Finally, this...
> +class Elementwise_vmul
> +{
> +public:
> + Elementwise_vmul();
> + ~Elementwise_vmul();
> +
> + template <typename T>
> + static void apply(T const *A, T const *B, T *R, length_type len);
> +
> +private:
> + spe_gid_t gid_;
> + speid_t speid_;
> + int status_;
> +};
...can become as generic as:
class SPE
{
public:
enum Op_code {..., vmul, vadd, fft_fwd, rfft_fwd, ...};
SPE();
~SPE();
template <typename R, typename A, typename B, ...>
void call(Op_code, R, A, B, ...);
};
And this...
> + Elementwise_vmul::apply(A, B, R, len);
...then becomes
SPE *spe = get_target_spe(SPE::vmul);
spe->call(SPE::vmul, r, a, b);
With that all the work is encapsulated into the 'get_target_spe()'
function (where we can determine which SPE is most fit for the call,
based on what is currently loaded there), as well as
SPE::call() (where we can determine what needs to be done to prepare
the SPE in order to execute this operation).
Thanks,
Stefan
--
Stefan Seefeld
CodeSourcery
stefan at codesourcery.com
(650) 331-3385 x718
More information about the vsipl++
mailing list