octave-maintainers
[Top][All Lists]
Advanced

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

Re: 3D versus 2D Indexing and the Speed Thereof


From: John W. Eaton
Subject: Re: 3D versus 2D Indexing and the Speed Thereof
Date: Wed, 6 Dec 2006 14:58:40 -0500

On 30-Nov-2006, Luis F. Ortiz wrote:

| On Wed, 2006-11-29 at 11:26 -0500, John W. Eaton wrote:
| 
| > On 29-Nov-2006, Luis F. Ortiz wrote:
| > 
| > | On Tue, 2006-11-21 at 03:16 -0500, John W. Eaton wrote:
| > | > OTOH, if Octave's Array class knew how to do slices and if we
| > | > recognized these operations as slices, then the time should be
| > | > constant here, not proportional to the number of elements copied.
| > | 
| > | So, lets pretend that I added a method to the Array class that looked
| > | something like this:
| > | 
| > |         // Maybe this should be in ArrayRep??
| > |         template <class T>
| > |         void
| > |         Array<T>::strip_gather(Array<T>& source, octave_idx_type
| > |         dest_offset, octave_idx_type source_offset,
| > |                            octave_idx_type element_count , 
| > |                      octave_idx_type strip_count ,
| > |                      octave_idx_type strip_stride)
| > |         {
| > |                 T *raw_source, *raw_dest;
| > |                 raw_source = & ( source.xelem(source_offset) );
| > |                 raw_dest = & ( xelem(dest_offset) );
| > |                 for (octave_idx_type i = 0 ; i < strip_count; ++i)
| > |                  {
| > |                     bcopy(raw_source,raw_dest,sizeof(T)*element_count);
| > |                     raw_source += strip_stride;
| > |                     raw_dest += element_count;
| > |                  }
| > |         }
| > 
| > You need to be careful to preserve the copy-on-write semantics of the
| > Array class.  The above doesn't appear to do that.
| 
| Gotchya..   I presume that copying the first element by hand using
| something like:
| 
|     elem(dest_offset) = source.elem(source_offset);
| 
| would trigger the COW and then make the subsequent block copy kosher.

Or, you can use fortran_vec.  Is source modified here?  If not, then I
think you should declare it const.  Then you can write something like

  // Maybe this should be in ArrayRep??
  template <class T>
  void
  Array<T>::strip_gather (const Array<T>& source,
                          octave_idx_type dest_offset,
                          octave_idx_type source_offset,
                          octave_idx_type element_count, 
                          octave_idx_type strip_count,
                          octave_idx_type strip_stride)
  {
    const T *raw_source = source.data () + source_offset;
    T *raw_dest = fortran_vec () + dest_offset;

    for (octave_idx_type i = 0; i < strip_count; i++)
      {
        memmove (raw_dest, raw_source, sizeof(T)*element_count);
        raw_source += strip_stride;
        raw_dest += element_count;
      }
  }

Is memmove really necessary here?  Why not just a loop over the
elements?

jwe


reply via email to

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