dotgnu-libjit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-libjit] Arithmetic operations and type-coercions for byte, short


From: Jan Wedekind
Subject: [Dotgnu-libjit] Arithmetic operations and type-coercions for byte, short int, ... ?
Date: Fri, 5 Sep 2008 08:52:34 +0100 (BST)

Hi,
  I'm developing a Ruby-extension for doing computer vision [1] with the
Ruby programming language and I am thinking about replacing the current C++ template implementation with an implementation based on
libjit and ruby-libjit [2].
  I need to generate code to do element-wise unary operations
(such as +,-) and binary (scalar-array,array-scalar,array-array) operations (such as +,-,*,/,**,minor,major). The element-types of the
two arrays can be various combinations of char, unsigned char, unsigned
short int, ...
  I noted that adding to 8-bit values with libjit results in a 32 bit
integer. Since I don't want to overwrite succeeding elements in the array,
I need to convert the result back to 8-bit. A performance comparison shows
that this also has an impact on the performance (see below).
I had a look at the methods "common_binary" and "apply_arith" and I am wondering whether one could extend the code to support coercions resulting in 8- or 16-bit values as well.
  Please let me know what you think and tell me if I overlooked something.
It would be really cool if I could get the same performance as a C/C++
implementation.

Regards
Jan

[1] http://www.wedesoft.demon.co.uk/hornetseye-api/
[2] http://github.com/cout/ruby-libjit/

=====================================

// g++ -O -DNDEBUG -o jittest jittest.cc -ljit
#include <boost/shared_array.hpp>
#include <iostream>
#include <jit/jit.h>
#include <sys/time.h>

// #define JIT

// #define JITTYPE jit_int
// #define JITTYPET jit_type_int

#define JITTYPE jit_short
#define JITTYPET jit_type_short

// #define JITTYPE jit_ubyte
// #define JITTYPET jit_type_ubyte

// AMD Athlon 64bit

// INT:
// G++: 0.00346661 s
// JIT: 0.00344854 s

// SHORT:
// G++: 0.00184178 s
// JIT: 0.00267739 s

// UBYTE:
// G++: 0.00154156 s
// JIT: 0.00222944 s

// http://lists.gnu.org/archive/html/dotgnu-libjit/2008-08/msg00004.html

#define SIZE 1000000
#define PRINT 20
#define COUNT 1000

using namespace std;

int main(void)
{
  jit_context_t context = jit_context_create();
  assert( context != NULL );

  boost::shared_array< JITTYPE > arr( new JITTYPE[ SIZE ] );
  for ( int i=0; i<SIZE; i++ )
    arr[i] = i;

#ifdef JIT
  jit_context_build_start( context );

  jit_type_t params[3];
  params[0] = jit_type_void_ptr;
  params[1] = jit_type_int;
  params[2] = jit_type_void_ptr;
  jit_type_t signature =
    jit_type_create_signature( jit_abi_cdecl, jit_type_void_ptr,
                               params, 3, 1 );

  jit_function_t function = jit_function_create( context, signature );
  // jit_function_set_recompilable( function );
  jit_value_t p, px, one, end, eq;
  jit_label_t start = jit_label_undefined;
  p = jit_value_get_param( function, 0 );
  one = jit_value_get_param( function, 1 );
  end = jit_value_get_param( function, 2 );
  jit_insn_label( function, &start );
  jit_value_t temp1 = jit_insn_load_relative( function, p, 0, JITTYPET );
  jit_value_t temp2 = jit_insn_add( function, temp1, one );
  jit_value_t temp3 = jit_insn_convert( function, temp2, JITTYPET, 0 );
  jit_insn_store_relative( function, p, 0, temp3 );
jit_value_t temp4 = jit_insn_add_relative( function, p, sizeof(JITTYPE) );
  jit_insn_store( function, p, temp4 );
  eq = jit_insn_lt( function, p, end );
  jit_insn_branch_if( function, eq, &start );
  jit_insn_return( function, p );

  jit_function_compile( function );

  jit_context_build_end( context );
#endif

  struct timeval time;
  gettimeofday( &time, NULL );
#ifdef JIT
  for ( int i=0; i<COUNT; i++ ) {
    void *args[3];
    jit_ptr arg1 = arr.get(); // + 1
    JITTYPE arg2 = 1;
    jit_ptr arg3 = arr.get() + SIZE; // + 2
    jit_ptr result;
    args[0] = &arg1;
    args[1] = &arg2;
    args[2] = &arg3;
    jit_function_apply( function, args, &result );
  };
#else
  for ( int i=0; i<COUNT; i++ ) {
    JITTYPE *p = arr.get();
    JITTYPE *end = arr.get() + SIZE;
    for ( ; p != end; p++ )
      *p += 2;
  };
#endif
  struct timeval time2;
  gettimeofday( &time2, NULL );
  struct timeval difference;
  timersub( &time2, &time, &difference );

  cout << ( ( difference.tv_sec + difference.tv_usec * 1.0E-6 ) / COUNT )
       << " s" << endl;
  cout << "[ " << (int)arr[0];
  for ( int i=1; i<PRINT; i++ )
    cout << ", " << (int)arr[i];
  cout << " ]" << endl;

  jit_context_destroy( context );

  return 0;
}

=====================================





reply via email to

[Prev in Thread] Current Thread [Next in Thread]