[pooma-dev] RFA: delete_test1 Modifications

Jeffrey Oldham oldham at codesourcery.com
Thu May 24 20:48:33 UTC 2001


For those skipping intermediary emails, the discussion is whether
memmove() is faster than copy().

Attached is a program that constructs a vector, copies its contents to
another vector, and then checks the copy for correctness.  On
Linux/gcc3.0 and Irix6.5/KCC, I cannot find any significant speed
difference between std::copy and std::memmove for vectors of doubles.
Given this result, may we use std::copy() everywhere since it is
guaranteed to compile?

Thanks,
Jeffrey D. Oldham
oldham at codesourcery.com


On Thu, May 24, 2001 at 09:49:24AM -0700, James Crotinger wrote:
> Actually, I think "fast code" is one of our prime directives. We should try
> to find a way to do both. 
> 
>   Jim
> 
> > -----Original Message-----
> > From: Jeffrey Oldham [mailto:oldham at codesourcery.com]
> > Sent: Thursday, May 24, 2001 10:46 AM
> > To: James Crotinger
> > Cc: pooma-dev at pooma.codesourcery.com
> > Subject: Re: [pooma-dev] RFA: delete_test1 Modifications
> > 
> > 
> > On Thu, May 24, 2001 at 09:33:45AM -0700, James Crotinger wrote:
> > > The memmove optimization was fairly substantial when I 
> > tested it. I think it
> > > would be better to modify the code to pass addresses to 
> > memmove - again this
> > > gets to the question of whether it is really OK to use 
> > &a.begin()[0] to be
> > > the address of the 0th element, etc.
> > 
> > Yes, I imagine that memmove() is significantly faster than copy(), but
> > I would prefer to have code that is guaranteed to compile rather than
> > fast code that compiles only for certain platforms.
> > 
> > > > -----Original Message-----
> > > > From: Jeffrey Oldham [mailto:oldham at codesourcery.com]
> > > > Sent: Wednesday, May 23, 2001 6:33 PM
> > > > To: pooma-dev at pooma.codesourcery.com
> > > > Subject: [pooma-dev] RFA: delete_test1 Modifications
> > > > 
> > > > 
> > > > OK to commit?
> > > > 
> > > > Compiling src/Utilities/tests/delete_test1.cpp showed 
> > that the vector
> > > > type `Array_t' was declared to store doubles but actually stored
> > > > integers.  Also, a call to std::memmove() illegally 
> > converted vector
> > > > iterators to pointers.  The alternative call to 
> > std::copy() is instead
> > > > used.
> > > > 
> > > > 2001 May 23  Jeffrey D. Oldham  <oldham at codesourcery.com>
> > > > 
> > > > 	* delete_test1.cpp (Array_t): s/vector<double>/vector<int>/
> > > > 	(delete_shiftup_test2): Remove "optimization" call to memmove.
> > > > 
> > > > Tested on	sequential Linux using gcc 3.0 by compiling the program
> > > > Approved by	???you???
> > 
> > Thanks,
> > Jeffrey D. Oldham
> > oldham at codesourcery.com
> > 

-- 
Jeffrey D. Oldham
oldham at codesourcery.com
-------------- next part --------------
// Program to compare times for std::copy, std::copy_n, and
// std::memmove.  If copying from one vector to the other fails,
// either a nonzero return value is returned (if printing is turned
// off) or a message is printed out.

// Command-line arguments:
// 1. size of vector to copy
// 2. name of function to use: "copy" or "copy_n" or "memmove"

// To print information while the program is running, compile with
// "PRINT" defined.


#include <iterator>
#include <iostream>
#include <vector>
#include <cstdlib>
#include <algorithm>	// has equal() and copy()
#include <string.h>	// has strcasecmp()


int main(int argc, char *argv[])
{
  typedef std::vector<double> vector_t;

  // Process the command-line arguments.
  if (argc != 3) {
    std::cerr << argv[0] << ": vector_size copy_function\n";
    return EXIT_FAILURE;
  }
  vector_t::size_type vectorSize = strtoul(argv[1], static_cast<char **>(0), 0);

  // Construct the original vector.
  vector_t v;
  vector_t vCopy (vectorSize);
  for (vector_t::size_type size = vectorSize; size > 0; --size)
    v.push_back(size);
#ifdef PRINT
  std::cout << "Hello, world" << std::endl;
  std::cout << "v's size: " << v.size () << std::endl;
  // TMP typedef vector_t::iterator iter_t;
  // TMP fix the warning of unused variable.  It has no space. std::iterator_traits<iter_t >::pointer ptr;
  std::cout << "v contains:\n";
  std::copy(v.begin(), v.end(),
	      std::ostream_iterator<vector_t::value_type>(std::cout, " "));
  std::cout << std::endl;
#endif // PRINT

  // Copy the vector.
  if (strcasecmp (argv[2], "copy") == 0)
    std::copy(v.begin(), v.end(), vCopy.begin());
  else if (strcasecmp (argv[2], "copy_n") == 0)
    std::copy_n(v.begin(), vectorSize, vCopy.begin());
  else {  // std::memmove
    vector_t::pointer vBegin = &(v[0]);    
    vector_t::pointer vCopyBegin = &(vCopy[0]);
    std::memmove(static_cast<void *>(vBegin), static_cast<void *>(vCopyBegin),
		 vectorSize * sizeof(vector_t::value_type));
  }

  // Check the copy for correctness.
  if (std::equal(v.begin(), v.end(), vCopy.begin())) {
#ifdef PRINT
    std::cout << "Copied vector equals the original vector.\n";
#else
    ;
#endif // PRINT
  }
  else {
#ifndef PRINT
    return EXIT_FAILURE;
#else
    std::cout << "Oops! Copied vector does not equal the original vector.\n";
    std::cout << "Original vector:\n";
    std::copy(v.begin(), v.end(),
	      std::ostream_iterator<vector_t::value_type>(std::cout, " "));
    std::cout << std::endl;
    std::cout << "Copied vector:\n";
    std::copy(vCopy.begin(), vCopy.end(),
	      std::ostream_iterator<vector_t::value_type>(std::cout, " "));
    std::cout << std::endl;
#endif // PRINT
  }

#ifdef PRINT
  std::cout << "Goodbye, world" << std::endl;
#endif // PRINT
  return 0;
}


More information about the pooma-dev mailing list