forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[WIP] A very special (and weird) template library for VFPU

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Mon Apr 07, 2008 4:58 am    Post subject: [WIP] A very special (and weird) template library for VFPU Reply with quote

I'm working on a special VFPU lib for C++, using template classes a lot.

The main idea is to let g++ to allocate vfpu registers and try to compute without the need to struggle with the assembly code. But the drawback is the way you write the algorithm using vfpu, because it would appear to most people very weird.

that code :

Code:

#include "vfpu.h"

extern "C" void vector2d_sample_linear(float *vector_result, float *vector_source, float *vector_target, float &alpha)
{
   // load scalar alpha in a new register
   typedef vfpu_scalar_load< vfpu_scalar_new_reg < > >
      load_alpha, step1;
   
   // load 2d vector source in a new register
   typedef vfpu_vector_2d_load< vfpu_vector_new_reg < step1 > >
      load_vector_source, step2;
   
   // load 2d vector target in a new register
   typedef vfpu_vector_2d_load< vfpu_vector_new_reg < step2 > >
      load_vector_target, step3;

   // saturated one's complement : { 1-alpha, alpha } = { (1.0 - alpha)[0..1], alpha[0..1] }
   typedef vfpu_vector_2d_socp_result< load_alpha, step3 >
      compute_alpha_and_one_minus_alpha, step4;

   typedef vfpu_vector_2d_scl_result< load_vector_source, vfpu_vector_2d_component< compute_alpha_and_one_minus_alpha, 0 >, step4 >
      scale_source_vector_with_one_minus_alpha, step5;

   typedef vfpu_vector_2d_scl_result< load_vector_target, vfpu_vector_2d_component< compute_alpha_and_one_minus_alpha, 1 >, step5 >
      scale_target_vector_with_alpha, step6;

   // Vs * (1.0 - alpha)[0..1] + Vd * alpha[0..1]
   typedef vfpu_vector_2d_add_result< scale_source_vector_with_one_minus_alpha, scale_target_vector_with_alpha, step6 >
      add_vectors_source_and_target, step7;


   // and store to vector result
   typedef vfpu_vector_2d_store< add_vectors_source_and_target, step7 >
      store_vector_result;

   // execute
   load_alpha         _1(alpha);
   load_vector_source _2(*vector_source);
   load_vector_target _3(*vector_target);
   
   compute_alpha_and_one_minus_alpha();
   scale_source_vector_with_one_minus_alpha();
   scale_target_vector_with_alpha();
   add_vectors_source_and_target();

   store_vector_result _(*vector_result);
}


gives me :
Code:
00000018 <vector2d_sample_linear>:

// load scalar alpha in a new register
  18:   c8e00000        lv.s    S000.s,0(a3)

// load 2d vector source in a new register
  1c:   c8a10000        lv.s    S010.s,0(a1)
  20:   c8a10005        lv.s    S011.s,4(a1)

// load 2d vector target in a new register
  24:   c8c20000        lv.s    S020.s,0(a2)
  28:   c8c20005        lv.s    S021.s,4(a2)

// saturated one's complement : { 1-alpha, alpha } = { (1.0 - alpha)[0..1], alpha[0..1] }
  2c:   d0450103        vsocp.s C030.p,S000.s

// scale vector source with 1-alpha
  30:   65030184        vscl.p  C100.p,C010.p,S030.s

// scale vector target with alpha
  34:   65230285        vscl.p  C110.p,C020.p,S031.s

// add vectors source and target to vector result
  38:   60050486        vadd.p  C120.p,C100.p,C110.p

// store vector result
  3c:   e8860000        sv.s    S120.s,0(a0)
  40:   e8860005        sv.s    S121.s,4(a0)

// exit function
  44:   03e00008        jr      ra
  48:   00000000        nop


which is pretty good for what i was expected.

I dunno if somebody may be interested in this library.

Sure, there is still a lot of job to do.

NOTE :

any vfpu_vector_2d_XXX template class has an optional template parameter named "clobbered" (those ones named "stepN" in my example) which allows g++ to remember which VFPU registers were "allocated". This is the main reason why we need so many typedefs and this weird syntax.
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Thu Apr 10, 2008 8:21 am    Post subject: Reply with quote

in loop, it is not bad :

Code:
extern "C" void vector_2d_sample_linear(float *vector_result, float *vector_source, float *vector_target, float &alpha, int n)
{
   typedef vfpu_vector_new_register<                   > vector_source_reg;
   typedef vfpu_vector_new_register< vector_source_reg > vector_target_reg;
   typedef vfpu_scalar_new_register< vector_target_reg > alpha_reg;

   // saturated one's complement : { 1-alpha, alpha } = { (1.0 - K)[0..1], K[0..1] }
   typedef vfpu_vector_2d_socp_result< alpha_reg >
      alpha_and_one_minus_alpha;

   typedef vfpu_vector_2d_scl_result< vector_source_reg, vfpu_vector_2d_component< alpha_and_one_minus_alpha, 0 > >
      scaled_vector_source_with_one_minus_alpha;

   typedef vfpu_vector_2d_scl_result< vector_target_reg, vfpu_vector_2d_component< alpha_and_one_minus_alpha, 1 >, scaled_vector_source_with_one_minus_alpha >
      scaled_vector_target_with_alpha;

   // Vs * (1.0 - K)[0..1] + Vd * K[0..1]
   typedef vfpu_vector_2d_add_result< scaled_vector_source_with_one_minus_alpha, scaled_vector_target_with_alpha >
      result;

   // load alpha
   vfpu_scalar_load(alpha_reg(), alpha);

   // saturate alpha between 0 and 1 then compute one minus alpha
   alpha_and_one_minus_alpha();

   // for n vectors
   for (int i = 0; i < n; vector_result+=2)
   {
      // load source and target vectors
      vfpu_vector_2d_load(vector_source_reg(), vector_source[0], vector_source[1]);
      vfpu_vector_2d_load(vector_target_reg(), vector_target[0], vector_target[1]);

      vector_source+=2;

      // compute new source and target vectors
      scaled_vector_source_with_one_minus_alpha();
      scaled_vector_target_with_alpha();
      
      vector_target+=2;
      
      ++i;

      // and add them to get the result vector
      vfpu_vector_2d_store(result(), vector_result[0], vector_result[1]);
   }
}


gives me :

Code:
00000030 <vector_2d_sample_linear>:
  30:   c8e20000        lv.s    S020.s,0(a3)
  34:   d0450203        vsocp.s C030.p,S020.s
  38:   1900000f        blez    t0,78 <vector_2d_sample_linear+0x48>
  3c:   00001021        move    v0,zero
  40:   c8a00000        lv.s    S000.s,0(a1)
  44:   c8a00005        lv.s    S001.s,4(a1)
  48:   c8c10000        lv.s    S010.s,0(a2)
  4c:   c8c10005        lv.s    S011.s,4(a2)
  50:   24a50008        addiu   a1,a1,8
  54:   65030084        vscl.p  C100.p,C000.p,S030.s
  58:   65230185        vscl.p  C110.p,C010.p,S031.s
  5c:   24c60008        addiu   a2,a2,8
  60:   24420001        addiu   v0,v0,1
  64:   60050486        vadd.p  C120.p,C100.p,C110.p
  68:   e8860000        sv.s    S120.s,0(a0)
  6c:   e8860005        sv.s    S121.s,4(a0)
  70:   1502fff3        bne     t0,v0,40 <vector_2d_sample_linear+0x10>
  74:   24840008        addiu   a0,a0,8
  78:   03e00008        jr      ra
  7c:   00000000        nop


some integer increments are inserted between vfpu instruction, that's very good for reducing lantency between vfpu instructions.


Last edited by hlide on Fri Apr 11, 2008 5:59 am; edited 1 time in total
Back to top
View user's profile Send private message
gauri



Joined: 20 Jan 2008
Posts: 35
Location: Belarus

PostPosted: Thu Apr 10, 2008 3:42 pm    Post subject: Reply with quote

so implementin intrinsics didn't prove itself really feasible?

can you share the whole library? i'm really interested in that.
_________________
Freelance game industry veteran. 8]
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Fri Apr 11, 2008 5:56 am    Post subject: Reply with quote

gauri wrote:
so implementin intrinsics didn't prove itself really feasible?

can you share the whole library? i'm really interested in that.


this is a very HUGE work to add intrinsics.

I plan to share this library as soon as possible. But it is too early to release it as I want to experiment with it and find different ways to implement this library in the most efficient way. When I started it that last weekend, I was just playing and I didn't really expect such a result without having to tweak psp-gcc for vfpu.

By the way, it seems psp-as is buggy for vfpu :

"vmov.p C010, C002" works fine but not "vmov.p $1, $64" whereas they are strictly the same thing. I have an error with a vfpu register $64 or above. It is such a pity because I really need to use the '$' register notation for my library. :/
Back to top
View user's profile Send private message
hlide



Joined: 10 Sep 2006
Posts: 750

PostPosted: Mon Apr 21, 2008 11:09 am    Post subject: Reply with quote

gauri wrote:
so implementin intrinsics didn't prove itself really feasible?

can you share the whole library? i'm really interested in that.


ok, still not complete. I was mainly trying to make a 2d lib using vfpu but there is no reason not to extend it to a 3d or quaternion lib. I'm not totally satisfied with it, but i can see it as a good start.

svn://svn2.assembla.com/svn/pspvftl/trunk/pspvftl/
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group