memset and OOP in singular

30 views
Skip to first unread message

Benjamin Schnitzler

unread,
May 3, 2013, 1:19:42 PM5/3/13
to singula...@googlegroups.com, grischa.s...@rwth-aachen.de, leva...@math.rwth-aachen.de
Dear Singular Developement Team (SDT),

recently I stumbled about the memset instructions in some of
the singular functions, especially in the object constructors
of skStrategy, sLObject, sTObject. Whilst I can understand the
need for speed for the singular implementation, I think, that
memset for c++ objects is not the means of choice. This little
memset instruction interferes with some fundamental Object-oriented
programming (OOP) paradigms/techniques, e.g. polymorphism or
Composition of Objects. I wouldn't have noticed it, if I did not run
into problems myself. In short: I could patch the constructors of
these classes, to use an initializer list, instead of memset,
to set their members to 0. And I hope you (the SDT) are interested to
apply those patches. If you are interested in what I do at the
moment, I can give you an overview about how I am
using/(trying to use) OOP in Singular at the moment.
If you would like to have some further information about what
problems memset can cause, have a look at this:
https://augias.org/paercebal/tech_doc/doc.en/cp.memset_is_evil.html
Well, I do not want to imply that memset is evil, but this short
article is quite readable and has the necessary information.
(In particular: Have a look at the section "memset vs. non-POD".)

Furthermore (if you are still willingly to read on):
As I already stated, the Removal of the memset instruction from
some places of the singular code is also personal concern of me.
But maybe this could be the place to offer some of my thinkings
about OOP in Singular in general. I don't know anything about
the plans of the SDT in this matter, but I am eager to hear
something about them. Already I heard of the plans of
Oleksandr Motsak to renew the template system of singular, but
as far as I can remember, there was yet no consent about it.
Are there still plans to develope in this direction? What other
plans has the SDT? Some thoughts of me:
� Apply encapsulation to the members of the Objects, use
getters/setters, declare most members private.
� Split code in a c++ way. E.g. skStrategy seems to be an
accumulation of many different algorithmic parts of Singular.
This can make improvement and changes to it rather cumbersome.
Here one can use Inheritance and maybe some Interfaces for
sLObject and sTObject would be useful.
� Use C++ Namespace additionally: Not everything fits into a
class. Namespaces make clear, which part of the code belongs
where (and help to avoid name clashes).
� Document some of the code e.g. with doxygen or something like
that. (Ok, this was a joke, but it would be handy to have a
better documentation of the code.)
� A minor matter: Instead of having concrete Objects in say a
class like skStrategy, it may be better to have pointers,
since then, when one inherits (for example) from sLObject,
one can initialize these pointers whith the inherited Object,
instead of the normal sLObject (so there is no need to carry
these around). But that may not be of great importance. I
just got this idea, because I am in exact this situation.
After having done this, one could look for some other Software
Engeneering techniques to apply on the Singular code. However,
these are just some thoughts of mine and for sure the SDT is
quite busy at the moment. I may be able to help you a bit in
the future.

My Question for you:
Would you possibly apply the patch I could send to you,
or are you not interested in removing the memset instructions,
or do you want to do it on your own?

Benjamin Schnitzler

han...@mathematik.uni-kl.de

unread,
May 7, 2013, 9:10:15 AM5/7/13
to singula...@googlegroups.com
On Fri, May 03, 2013 at 07:19:42PM +0200, Benjamin Schnitzler wrote:
> Dear Singular Developement Team (SDT),
>
> recently I stumbled about the memset instructions in some of
> the singular functions, especially in the object constructors
> of skStrategy, sLObject, sTObject. Whilst I can understand the
> need for speed for the singular implementation, I think, that
> memset for c++ objects is not the means of choice. This little
> memset instruction interferes with some fundamental Object-oriented
> programming (OOP) paradigms/techniques, e.g. polymorphism or
> Composition of Objects. I wouldn't have noticed it, if I did not run
> into problems myself. In short: I could patch the constructors of
> these classes, to use an initializer list, instead of memset,
> to set their members to 0. And I hope you (the SDT) are interested to
> apply those patches. If you are interested in what I do at the
> moment, I can give you an overview about how I am
> using/(trying to use) OOP in Singular at the moment.
> If you would like to have some further information about what
> problems memset can cause, have a look at this:
> https://augias.org/paercebal/tech_doc/doc.en/cp.memset_is_evil.html
> Well, I do not want to imply that memset is evil, but this short
> article is quite readable and has the necessary information.
> (In particular: Have a look at the section "memset vs. non-POD".)
Dear Benjamain,
in principle the objectives against memset boils down to:
- memset has bad effects if used in a wrong way
True, but this applies to nearly all faetures/functions of C++
- memset is not inlined while constructors are
Wrong, all optimizing compilers produce inline code for memset
- one should not do not care about memory layout
Bad idea(TM):
struct { bool a; double b; bool c; }: 24 bytes
struct { double b; bool a; bool b}: 16 bytes, i.e. 33 % faster
>
> Furthermore (if you are still willingly to read on):
> As I already stated, the Removal of the memset instruction from
> some places of the singular code is also personal concern of me.
> But maybe this could be the place to offer some of my thinkings
> about OOP in Singular in general. I don't know anything about
> the plans of the SDT in this matter, but I am eager to hear
> something about them. Already I heard of the plans of
> Oleksandr Motsak to renew the template system of singular, but
> as far as I can remember, there was yet no consent about it.
> Are there still plans to develope in this direction? What other
> plans has the SDT? Some thoughts of me:
> � Apply encapsulation to the members of the Objects, use
> getters/setters, declare most members private.
Good idea, but one should also avoid getters/setters:
the data within skStratgy should not be used outside of the Groebner base
machine
> � Split code in a c++ way. E.g. skStrategy seems to be an
> accumulation of many different algorithmic parts of Singular.
> This can make improvement and changes to it rather cumbersome.
> Here one can use Inheritance and maybe some Interfaces for
> sLObject and sTObject would be useful.
skStrategy contains the state of the Groebner base engine
(and only that):
it must be avaible inside and should not be used outside.
Further splitting will not work: would make the use of common
routines for all variants impossible.
> � Use C++ Namespace additionally: Not everything fits into a
> class. Namespaces make clear, which part of the code belongs
> where (and help to avoid name clashes).
Yes, we plan to use C++ namespaces (for Singular as a library).
But this does not help here, as this all happens inside ONE namespace.
> � Document some of the code e.g. with doxygen or something like
> that. (Ok, this was a joke, but it would be handy to have a
> better documentation of the code.)
We are doing that already (see subdir dox).
> � A minor matter: Instead of having concrete Objects in say a
> class like skStrategy, it may be better to have pointers,
> since then, when one inherits (for example) from sLObject,
> one can initialize these pointers whith the inherited Object,
> instead of the normal sLObject (so there is no need to carry
> these around). But that may not be of great importance. I
> just got this idea, because I am in exact this situation.
Good idea, but pointers must point (in the end) to the real data,
and that is exactly what sLObject/etc is for.
So we (nearly) never used skStrategy, only the pointer kStrategy strat
is passed around. Also sLObject is seldomly used, LObject (the pointer) is often used.
> After having done this, one could look for some other Software
> Engeneering techniques to apply on the Singular code. However,
> these are just some thoughts of mine and for sure the SDT is
> quite busy at the moment. I may be able to help you a bit in
> the future.
>
> My Question for you:
> Would you possibly apply the patch I could send to you,
> or are you not interested in removing the memset instructions,
> or do you want to do it on your own?
>
> Benjamin Schnitzler
>
After all these ideological stuff back the the real example:

sLObject/sTObject is used in form of a dynamic array.
Therefore we have to initialize the array elements (of type
sLObject/sTObject) whenever the size of the array increases.
This cannot be done by the constructor (the objects are not constructed
by this operation) so we rely on the memory manager for that
which have to use memset.
For that reason the constructors for sLObject/sTObject are
mostly useless (i.e. only used in special cases).

We want to have patches for Singular,
but memset and especially sLObject/sTObject are a really bad(TM) starting point.

Hans Schoenemann

Benjamin Schnitzler

unread,
May 7, 2013, 12:01:10 PM5/7/13
to singula...@googlegroups.com
Dear Hans,

I know, You don't have much time, so thank You for reading my mail.

On 15:10 Tue 07 May , han...@mathematik.uni-kl.de wrote:
> On Fri, May 03, 2013 at 07:19:42PM +0200, Benjamin Schnitzler wrote:
> > Dear Singular Developement Team (SDT),

> > Well, I do not want to imply that memset is evil, but this short
> > article is quite readable and has the necessary information.
> > (In particular: Have a look at the section "memset vs. non-POD".)
> Dear Benjamain,
> in principle the objectives against memset boils down to:
> - memset has bad effects if used in a wrong way
> True, but this applies to nearly all faetures/functions of C++
> - memset is not inlined while constructors are
> Wrong, all optimizing compilers produce inline code for memset
> - one should not do not care about memory layout
> Bad idea(TM):
> struct { bool a; double b; bool c; }: 24 bytes
> struct { double b; bool a; bool b}: 16 bytes, i.e. 33 % faster
It's always good to have some advice of somebody, who has more insight
into C related memory management. I was actually unaware of this memory
alignment until today.

> > � Apply encapsulation to the members of the Objects, use
> > getters/setters, declare most members private.
> Good idea, but one should also avoid getters/setters:
> the data within skStratgy should not be used outside of the Groebner base
> machine
Hm, yes. Maybe we do not need getters and setters, though I don't see any
reason against them. One Aspect of using getters/setters is of course,
to hide structural information about an object, making it easier to
change it, if the situation demands that. But ok, maybe that will
never be necessary.

> > � Document some of the code e.g. with doxygen or something like
> > that. (Ok, this was a joke, but it would be handy to have a
> > better documentation of the code.)
> We are doing that already (see subdir dox).
Ah, another thing, I wasn't aware of. Good to hear.

> > � A minor matter: Instead of having concrete Objects in say a
> > class like skStrategy, it may be better to have pointers,
> > since then, when one inherits (for example) from sLObject,
> > one can initialize these pointers whith the inherited Object,
> > instead of the normal sLObject (so there is no need to carry
> > these around). But that may not be of great importance. I
> > just got this idea, because I am in exact this situation.
> Good idea, but pointers must point (in the end) to the real data,
> and that is exactly what sLObject/etc is for.
> So we (nearly) never used skStrategy, only the pointer kStrategy strat
> is passed around. Also sLObject is seldomly used, LObject (the pointer) is often used.
Well, I think my Explanation wasn't clear enought. I applied
some inheritance to sLObject and sTObject, which looks like
this:
/* Inheritance:
*
* sTObject
* / \
* / (virtual)\
* / \
* sLObject ShiftDVec::sTObject
* \ /
* \ /
* \ /
* ShiftDVec::sLObject
*
* see: SDkutil.h
*/
So instead of sTObject and sLObject, I use ShiftDVec::sTObject
and ShiftDVec::sLObject . Now an sLObject P is part of skStrategy.
However I inherited von skStrategy to ShiftDVec::skStrategy and
had to introduce another L into the derived skStrategy, which
I wouldn't need, if P was of pointer type. But, as I said,
this is just a minor issue. And regarding the last point of your
mail, it becomes clear, that I shouldn't use inheritance for
these objects at all, due to the internal memory management of
Singular.

> After all these ideological stuff back the the real example:
>
> sLObject/sTObject is used in form of a dynamic array.
> Therefore we have to initialize the array elements (of type
> sLObject/sTObject) whenever the size of the array increases.
> This cannot be done by the constructor (the objects are not constructed
> by this operation) so we rely on the memory manager for that
> which have to use memset.
> For that reason the constructors for sLObject/sTObject are
> mostly useless (i.e. only used in special cases).
Ok, then I'm lost ;) .

> We want to have patches for Singular,
> but memset and especially sLObject/sTObject are a really bad(TM) starting point.
Ok, I think I have to accept that.

Benjamin Schnitzler
Reply all
Reply to author
Forward
0 new messages