I have absolutely no efficiency concerns. The cpu cycles will be totally
negligible compared to the time to copy the memory. To be honest I rarely
stress about efficiency. Premature optimisation is usually a bad thing – don't
forget that the compiler has the ability to totally optimise away your classes
anyway if it sees fit.
My concern is more style and maintenance related. Placing all the communication
code in one class or a family of parent and child classes makes sense logically
which makes maintenance easier and allows different communication methods to be
swapped in should we need in the future – for example it would mean that the
change from the current ipc method to a new one would be a single line of code,
once that new method is written.
If the idea of creating a “null” object then calling a create method to fully
initialise it does not sit right with you then you could instead set up the
private member as a pointer which is initialised to null and use new to create
the object when needed. But this doesn't really have any advantages. The class
could have a method called something like isInitialised which allows it to be
checked just like checking a pointer is null. But with a pointer there could be
a path where its deletion is missed and the pointer goes out of scope and
resources leak.
The other option is to use a smart pointer. This is a class that acts like a
pointer but will automatically delete the object when it is no longer needed –
the exact timing depends on the type of smart pointer, which may be shared or
unique.
This is the joy of C++ 😊 We can automate a lot of things that need to be dealt
with manually in C and if you make use of them it can avoid bugs ever
occurring. So it makes sense to use them to their max. Read the book I
recommended 😉 it actually has a whole section on writing a smart pointer class
– although it is a bit out of date, as since C++ 11 there are built in smart
pointers called std::unique_ptr and std::shared_ptr, but reading about how they
work from first principles is a really good intro to good C++ style.
Phil
Sent from my Windows 10 phone
From: Alan W. Irwin
Sent: 13 February 2017 19:05
To: Phil Rosenberg
Cc: PLplot development list
Subject: Re: [Plplot-devel] The status of the wxwidgets IPC development
On 2017-02-12 22:51-0800 Alan W. Irwin wrote:
> I plan to stick with my local instance approach for now (automatically
> constructing a PLTwoSemaphore instance and destroying it again for
> each call to my transmitBytes and receiveBytes methods), but move to
> the private object approach for efficiency later on once I understand
> (hopefully with some further help from you) exactly what it does at
> run time compared with the local instance approach.
Hi Phil:
I have thought a lot more about this efficiency question using my
current mental model of the private object approach (if we applied it
for the case of PLMemoryMap accessing PLTwoSemapores). Please correct
that mental model if I have made a mistake with it, but if that model
is correct, then I predict (see below) there will be negligible
efficiency differences between the present local instance approach and
the private object approach.
I assume to make PLTwoSemapores accessible as a private object from
PLMemoryMap, I would move the current code in the PLTwoSemapores
constructor to a create method, replace the current PLTwoSemapores
constructor with one without arguments that basically forces the two
semaphore addresses to be invalid (NULL) values, and move the current
destructor code to a delete method so the destructor becomes a no-op.
Then whenever PLMemoryMap was instantiated, the private PLTwoSemapores
object that is mentioned in its private: section is also automatically
instantiated (with the invalid addresses). Then within transmitBytes
and receiveBytes methods, the create method for the private
PLTwoSemapores object is called first, and the destroy method for that
same object is called last. And ultimately when the PLMemoryMap
object is destroyed, the no-op destructor for its private
PLTwoSemapores object is also automatically called.
If that is the correct model, then the code in create and destroy is
the same as in the current PLTwoSemapores instantiation and
destruction that occurs in the current transmitBytes and receiveBytes
methods. So is your efficiency concern not that create and destroy
code, but other code that must be executed if you do a full-blown
instantiation and destruction of the PLTwoSemapores object?
Or are you also concerned with the cpu cycles required to call the
create and destroy methods for PLTwoSemapores every time the
transmitBytes and receiveBytes methods were called? For example, you
_could_ call the appropriate create and destroy methods outside
transmitBytes and receiveBytes (and likely less often if you used a
lot of care), but I would prefer not to do that because that
non-locality makes the code much harder to understand (say when we
look at it again 5 years from now) and I believe the number of cpu
cycles saved should be negligible compared with the number of cpu
cycles actually required to execute transmitBytes and receiveBytes.
Come to think of it, the number of cpu cycles needed for a full-blown
instantiation and destruction of a PLTwoSemapores object within
transmitBytes and receiveBytes should also be negligible compared to
even just the cpu costs of the memcpy calls that do the necessary
chunking up of the array of bytes to be sent via shared memory with
transitBytes and the similar memcpy costs on the receiving end to
reassemble the array of bytes, and the argument becomes stronger if
you add in the times for sem_wait to finish on the transmission
and receive ends.
So unless my mental model above is incorrect, I predict we will find
no discernible difference in efficiency when comparing between the
current local instance approach and the private object approach at
least for the use of PLTwoSemapores by the transmitBytes and
receiveBytes methods of PLMemoryMap. But I am willing to implement
the private object approach variant (controlled by a preprocessing
macro) and measure its efficiency compared with the current local
instance approach to confirm (or disprove) that prediction, and once
we have those test results, we can decide which approach to take.
Alan
__________________________
Alan W. Irwin
Astronomical research affiliation with Department of Physics and Astronomy,
University of Victoria (astrowww.phys.uvic.ca).
Programming affiliations with the FreeEOS equation-of-state
implementation for stellar interiors (freeeos.sf.net); the Time
Ephemerides project (timeephem.sf.net); PLplot scientific plotting
software package (plplot.sf.net); the libLASi project
(unifont.org/lasi); the Loads of Linux Links project (loll.sf.net);
and the Linux Brochure Project (lbproject.sf.net).
__________________________
Linux-powered Science
__________________________
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Plplot-devel mailing list
Plplot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/plplot-devel