Results of the memswap() smackdown from the thread "Sorting"assignment - Programming Languages
This is a discussion on Results of the memswap() smackdown from the thread "Sorting"assignment - Programming Languages ; >>FGHDEABC, unless I'm missing something.
You are. It is not mathematically well defined (meaning it is ambiguous)
Even if you record both strings in separate buffers, when you recombine, it
is not obvious what the middle 2 characters should be. ...
-
Re: Results of the memswap() smackdown from the thread "Sorting" assignment
>>FGHDEABC, unless I'm missing something.
You are. It is not mathematically well defined (meaning it is ambiguous)
Even if you record both strings in separate buffers, when you recombine, it
is not obvious what the middle 2 characters should be. Should it be the 1st?
The 2nd? Randomly from one or the other?
You could write some code to do square matrix mutiplication asssuming that
it commutative. You then argue with others about whose is fastest/best/most
elegant. But the original assumption is wrong : matrix mutiplication is
_NOT_ generally commutitive. You look foolish for having embarked on a quest
that was never achievable from the start.
So all this accusation of why wasnt memmove() used from the word go in
mem_swap() is stupid: The problem is not well-defined to start with.
The original problem of swapping 2 non-overlapping objects for sort purposes
is well-defined.
Given that, memcpy() is fine.
Stephen Howe
-
Re: Results of the memswap() smackdown from the thread "Sorting" assignment
Ben Bacarisse said:
[color=blue]
> spinoza1111 <spinoza1111@yahoo.com> writes:[/color]
<snip>
[color=blue][color=green]
>> And I am not amused by Heathfield's conduct in this ng, which is to
>> constantly promote a bad language to the exclusion of other and better
>> paradigms (notably OO) and to trash personalities (such as Schildt)
>> for errors when in fact he has made a significant error in
>> recommending memcpy without remembering, as the C expert here, that it
>> is undefined for overlap.[/color]
>
> Did he?[/color]
No. (Neither am I "the C expert here" - several posters to comp.programming
know at least as much about C as I do, and some of them actually know
rather more.)
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
-
Re: Results of the memswap() smackdown from the thread "Sorting" assignment
Richard Harter said:
[color=blue]
> On Fri, 15 Feb 2008 18:30:04 +0000, Richard Heathfield
> <rjh@see.sig.invalid> wrote:
>[color=green]
>>Richard Harter said:
>>[color=darkred]
>>> On Fri, 15 Feb 2008 14:39:25 GMT, Randy Howard
>>> <randyhoward@FOOverizonBAR.net> wrote:
>>>
>>>>On Fri, 15 Feb 2008 07:49:32 -0600, spinoza1111 wrote
>>>>(in article
>>>><145b5420-c7b2-4ee4-91e3-26a97645cacc@h11g2000prf.googlegroups.com>):
>>>>
>>>
>>>>> Bad ****ogy. The problem in C is that it prevents people from
>>>>> "jogging", learning computer science, without first knowing bad
>>>>> practises such as "I can modify value parameters" and false
>>>>> propositions such as "there are two types of strings: strings with
>>>>> Nul, and strings without Nul".
>>>
>>> This should read "A problem with C" rather than "The problem in
>>> C".[/color]
>>
>>Not really. It is not evident that modifying parameters is inherently bad
>>practice. Nor does anyone who knows C claim that there are two types of
>>strings in that language. C defines "string" very closely - anyone who
>>wishes to use some other kind of 'string' would be wise to use an
>>adjective to make it clear that he is not referring to the kind of string
>>that C carefully defines.[/color]
>
> I was correcting his English, not his content.[/color]
Oh, I see. Sorry about that.
[color=blue]
> Without going
> through the thread and sifting out usage from context I have no
> idea what a "value parameter" might be,[/color]
Given the authorship, it could mean anything. But, given the C context, I
took it to mean "a parameter".
<snip>
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
-
Re: Results of the memswap() smackdown from the thread "Sorting" assignment
Randy Howard said:
<snip>
[color=blue]
> I think this is hopeless, Clive. Nilges doesn't see "broken" if his
> code runs to completion. Regardless what answer is spat out, if it
> compiles and doesn't crash, he "declares victory".[/color]
It's a very special moment.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
-
Re: Results of the memswap() smackdown from the thread "Sorting" assignment
Clive D. W. Feather said:
[color=blue]
> In article
> <aab44907-d9ee-4e0b-8725-14060c6fb8bd@d4g2000prg.googlegroups.com>,
> spinoza1111 <spinoza1111@yahoo.com> writes[color=green]
>>He has
>>compounded the problem by suggesting a byte by byte check for overlap,
>>or agreeing with same, when all that is needed to check overlap is
>>
>>assert(ptrToA + intLength <= ptrToB || ptrToB + intLength <= ptrToA);[/color]
>
> Wrong.[/color]
Quite so. But give him three or four days to catch up with why it's wrong
(I know you explained it to him, but it'll take more than that to get the
message through), and then no doubt he'll be telling us all how he knew it
all along and indeed warned us about it but he can't now find the post
where he did so because of the "blizzard of replies", the "thread
vandalism", and so on (as if the Google Groups archive didn't have a
search facility).
<snip>
[color=blue][color=green]
>>I warned the ng about the
>>unpredictability of memcpy() as actually implemented,[/color]
>
> Not about this, you didn't. You talked about people introducing less
> efficient code. It's just a coincidence that this domain limitation
> happened - one that I don't actually believe is significant in this
> context.[/color]
Well, of course it isn't. In fact, I only mentioned it in passing. But Mr
Nilges is in the position of a man who wishes to destroy a citadel, and
the only ammunition he can find is a few blades of grass being blown along
on the wind. So he finds himself jumping to catch them, and then loading
them into his trebuchet - one by one, or sometimes two or three at a time.
And, as they fly several inches towards the citadel before air resistance
sends them fluttering to his feet, you can hear him crying "take that, you
fiend!", and see him shaking his fist. It's really quite sad.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
-
Re: Results of the memswap() smackdown from the thread "Sorting" assignment
Richard Heathfield <rjh@see.sig.invalid> writes:
[color=blue]
> Ben Bacarisse said:
>[color=green]
>> spinoza1111 <spinoza1111@yahoo.com> writes:[/color]
>
> <snip>
>[color=green][color=darkred]
>>> <snip> he has made a significant error in
>>> recommending memcpy without remembering, as the C expert here, that it
>>> is undefined for overlap.[/color]
>>
>> Did he?[/color]
>
> No. <snip>[/color]
Of course not. I obviously failed to indicate the sarcastic tone of
the question. Next time I will try "Right, and I am Marie of
Romania"[1].
[1] [url]http://www.quotationspage.com/quote/126.html[/url] which might lighten
the tone of the now tedious collection of threads.
--
Ben.
-
Re: Results of the memswap() smackdown from the thread "Sorting" assignment
Ben Bacarisse said:
[color=blue]
> Richard Heathfield <rjh@see.sig.invalid> writes:
>[color=green]
>> Ben Bacarisse said:
>>[color=darkred]
>>> spinoza1111 <spinoza1111@yahoo.com> writes:[/color]
>>
>> <snip>
>>[color=darkred]
>>>> <snip> he has made a significant error in
>>>> recommending memcpy without remembering, as the C expert here, that it
>>>> is undefined for overlap.
>>>
>>> Did he?[/color]
>>
>> No. <snip>[/color]
>
> Of course not. I obviously failed to indicate the sarcastic tone of
> the question.[/color]
Well, it was obvious to *me*. But it won't have been obvious to our
resident bozo, however, so I thought I'd spell it out for him.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
-
Re: Results of the memswap() smackdown from the thread "Sorting" assignment
On Fri, 15 Feb 2008 17:40:49 -0600, spinoza1111 wrote
(in article
<0fe5a25d-2770-4382-a23a-ab0988183839@d21g2000prf.googlegroups.com>):
[color=blue]
> On Feb 16, 5:32 am, Randy Howard <randyhow...@FOOverizonBAR.net>
> wrote:[color=green]
>> On Fri, 15 Feb 2008 12:04:17 -0600, spinoza1111 wrote
>> (in article
>> <435d96e7-6c43-4534-9cfb-08c457eef...@s12g2000prg.googlegroups.com>):
>>[color=darkred]
>>> On Feb 16, 1:21 am, Richard Heathfield <r...@see.sig.invalid> wrote:
>>>> "Stephen Howe" <sjhoweATdialDOTpipexDOTcom> said:[/color]
>>[color=darkred]
>>>>> I doubt that he had forgotten memcpy() does not do overlap. It is a fact
>>>>> that once known is remembered by C and C++ programmers.
>>>>> Rather it is more the case that in all exercise with implementing
>>>>> mem_swap(), the domain issues were overlooked and not discussed.[/color]
>>[color=darkred]
>>>> You know that. I know that. But you will never persuade him of that.[/color]
>>[color=darkred]
>>> Do me the courtesy of addressing me, and admitting that you made a
>>> showstopper error. Say, "Ed, I have learned that I can make serious
>>> mistakes, of the sort for which I hounded you and Schildt".[/color]
>>
>> The only person that didn't know about it was you. It was the smoking
>> gun that we left laying there, and you never noticed until someone else
>> mentioned it. Do you even know what the proper method of doing a
>> memory copy with overlapping regions is?[/color]
>
> You're lying when you pretend that you knew about this problem,[/color]
Read the article where I specifically mentioned there being an issue
with the functions being discussed, and I asked if you would like to
know what it was.
--
Randy Howard (2reply remove FOOBAR)
"The power of accurate observation is called cynicism by those
who have not got it." - George Bernard Shaw
-
Re: Results of the memswap() smackdown from the thread "Sorting"assignment
On Feb 16, 3:08 am, "Bartc" <b...@freeuk.com> wrote:[color=blue]
> "Malcolm McLean" <regniz...@btinternet.com> wrote in message
>
> news:WomdneA2VdIxWijanZ2dneKdnZydnZ2d@bt.com...
>
>
>[color=green]
> > "spinoza1111" <spinoza1...@yahoo.com> wrote in message[color=darkred]
> >> We're seeing a laboratory example in which C is NOT "easier". Our
> >> resident C expert seems to have submitted code which doesn't handle
> >> overlap.[/color][/color]
>[color=green]
> > If you swap memory spaces rather than objects, inherently you cannot do
> > anything sensible on overlap - exept the special case where x and y are
> > identical.[/color][/color]
"Overlap swapping" may not be sensible but it's deterministic and
reversible in the sense of undoable because deterministic: it might be
useful in encoding.
The problem: "overlap swapping" is NOT reversible like this
swap(swap(blockA, blockB)) == blockA,blockB
It would seem to me that a memory swap should share this property with
swap of bytes where swap(swap(byte1, byte2)) = byte1,bytes
Fortunately, if you do not swap overlapping bytes then the swap is
reversible.
I believe the following code handles possible overlap. Once it hits a
point where block A byte x is inside block B, it hops to the end of
block B. Let's see, you don't need the opposite test (block B byte y
is inside block A), I think, because for any given byte, it "overlaps"
the corresponding byte iff the corresponding byte overlaps it.
You don't need a byte by byte precheck, or even my assert, this code
handles the checking as part of its main work. The listing is followed
by a preliminary test result. The test is instrumented so you can
watch the swap step by step. It swaps and then it unswaps. The results
and the code are best viewed in a monospace font.
void spinoza1111_memswap(char *ptrToA,
char *ptrToB,
int intLength)
{
printf("Swapping %d bytes at %d and %d\n",
intLength, ptrToA, ptrToB);
if (ptrToA + intLength > ptrToB
||
ptrToB + intLength > ptrToA)
printf("Overlap swap\n");
char chrExchange;
char *ptrToAend = ptrToA + intLength;
char *ptrToAwork = ptrToA;
char *ptrToBwork = ptrToB;
char *ptrToAstart;
char *ptrToBstart;
char *ptrToBblockLimit = ptrToB + intLength;
int intBlockLength;
printBlocks(ptrToA, ptrToB, intLength);
while (1)
{
do
{
if (ptrToAwork >= ptrToB && ptrToAwork < ptrToBblockLimit)
ptrToAwork += ptrToBblockLimit - ptrToB;
if (ptrToAwork >= ptrToAend) return;
if (*ptrToAwork != *ptrToBwork) break;
ptrToAwork++; ptrToBwork++;
}
while (1);
chrExchange = *ptrToAwork;
*ptrToAwork = *ptrToBwork;
*ptrToBwork = chrExchange;
printBlocks(ptrToA, ptrToB, intLength);
ptrToAwork++; ptrToBwork++;
}
}
#define ARRAY_SIZE_1 (10)
#define ARRAY_SIZE_2 (65)
char CHRmemswapTest[ARRAY_SIZE_1][ARRAY_SIZE_2] =
{"This is a test",
"A most egregious test.",
"Now is the time for all good men to come to the aid of the party",
"The quick brown fox jumped over the lazy dog.",
"I am thy Father's spirit",
"Condemn'd by night to walk the earth",
"Hope is the thing with feathers",
"That perches in the soul",
"And sings the tune without the words",
"And never stops at all"};
void printArray(void)
{
int intIndex1;
int intIndex2;
int intCount = 0;
for (intIndex1 = 0; intIndex1 < ARRAY_SIZE_1; intIndex1++)
{
for (intIndex2 = 0;
intIndex2 < ARRAY_SIZE_2;
intIndex2++)
{
printf("%c",
CHRmemswapTest[intIndex1][intIndex2]);
intCount++;
}
printf("\n");
printf("....5...10...15...20...25...30...35...40...45\n");
}
printf("\n\nNumber of lines: %d: Number of characters: %d\n\n\n",
intIndex1,
intCount);
}
#include <time.h>
#define ITERATIONS 100000
int main(int argc,char *argv[])
{
printArray();
int intIndex1;
double dblClock;
printf("%f\n", dblClock = clock());
printf("%d [%c%c%c%c%c%c%c%c%c%c] %d [%c%c%c%c%c%c%c%c%c%c]\n",
&(CHRmemswapTest[0][0]),
CHRmemswapTest[0][0],
CHRmemswapTest[0][1],
CHRmemswapTest[0][2],
CHRmemswapTest[0][3],
CHRmemswapTest[0][4],
CHRmemswapTest[0][5],
CHRmemswapTest[0][6],
CHRmemswapTest[0][7],
CHRmemswapTest[0][8],
CHRmemswapTest[0][9],
&(CHRmemswapTest[0][3]),
CHRmemswapTest[0][3],
CHRmemswapTest[0][4],
CHRmemswapTest[0][5],
CHRmemswapTest[0][6],
CHRmemswapTest[0][7],
CHRmemswapTest[0][8],
CHRmemswapTest[0][9],
CHRmemswapTest[0][10],
CHRmemswapTest[0][11],
CHRmemswapTest[0][12]);
spinoza1111_memswap(&(CHRmemswapTest[0][0]),
&(CHRmemswapTest[0][3]),
10);
printf("%d [%c%c%c%c%c%c%c%c%c%c] %d [%c%c%c%c%c%c%c%c%c%c]\n",
&(CHRmemswapTest[0][0]),
CHRmemswapTest[0][0],
CHRmemswapTest[0][1],
CHRmemswapTest[0][2],
CHRmemswapTest[0][3],
CHRmemswapTest[0][4],
CHRmemswapTest[0][5],
CHRmemswapTest[0][6],
CHRmemswapTest[0][7],
CHRmemswapTest[0][8],
CHRmemswapTest[0][9],
&(CHRmemswapTest[0][3]),
CHRmemswapTest[0][3],
CHRmemswapTest[0][4],
CHRmemswapTest[0][5],
CHRmemswapTest[0][6],
CHRmemswapTest[0][7],
CHRmemswapTest[0][8],
CHRmemswapTest[0][9],
CHRmemswapTest[0][10],
CHRmemswapTest[0][11],
CHRmemswapTest[0][12]);
spinoza1111_memswap(&(CHRmemswapTest[0][0]),
&(CHRmemswapTest[0][3]),
10);
printf("%d [%c%c%c%c%c%c%c%c%c%c] %d [%c%c%c%c%c%c%c%c%c%c]\n",
&(CHRmemswapTest[0][0]),
CHRmemswapTest[0][0],
CHRmemswapTest[0][1],
CHRmemswapTest[0][2],
CHRmemswapTest[0][3],
CHRmemswapTest[0][4],
CHRmemswapTest[0][5],
CHRmemswapTest[0][6],
CHRmemswapTest[0][7],
CHRmemswapTest[0][8],
CHRmemswapTest[0][9],
&(CHRmemswapTest[0][3]),
CHRmemswapTest[0][3],
CHRmemswapTest[0][4],
CHRmemswapTest[0][5],
CHRmemswapTest[0][6],
CHRmemswapTest[0][7],
CHRmemswapTest[0][8],
CHRmemswapTest[0][9],
CHRmemswapTest[0][10],
CHRmemswapTest[0][11],
CHRmemswapTest[0][12]);
printArray();
return 0;
}
Overlap swap
4235424, This is a
4235427, s is a tes
4235424, shiT is a
4235427, T is a tes
4235424, s iThis a
4235427, This a tes
4235424 [s iThis a ] 4235427 [This a tes]
Swapping 10 bytes at 4235424 and 4235427
Overlap swap
4235424, s iThis a
4235427, This a tes
4235424, T ishis a
4235427, shis a tes
4235424, This is a
4235427, s is a tes
4235424 [This is a ] 4235427 [s is a tes]
This is a test
....5...10...15...20...25...30...35...40...45
A most egregious test.
....5...10...15...20...25...30...35...40...45
Now is the time for all good men to come to the aid of the party
....5...10...15...20...25...30...35...40...45
The quick brown fox jumped over the lazy dog.
....5...10...15...20...25...30...35...40...45
I am thy Father's spirit
....5...10...15...20...25...30...35...40...45
Condemn'd by night to walk the earth
....5...10...15...20...25...30...35...40...45
Hope is the thing with feathers
....5...10...15...20...25...30...35...40...45
That perches in the soul
....5...10...15...20...25...30...35...40...45
And sings the tune without the words
....5...10...15...20...25...30...35...40...45
And never stops at all
....5...10...15...20...25...30...35...40...45
Number of lines: 10: Number of characters: 650
-
Re: Results of the memswap() smackdown from the thread "Sorting"assignment
On Feb 16, 3:51 am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:[color=blue]
> spinoza1111<spinoza1...@yahoo.com> writes:[color=green]
> > On Feb 14, 12:02 am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:[color=darkred]
> >>spinoza1111<spinoza1...@yahoo.com> writes:[/color][/color]
>[color=green][color=darkred]
> >> <snip>[/color][/color]
>[color=green][color=darkred]
> >> > If this is a test of programming skill, or just the effectiveness of
> >> > memswap, Ben's the clear winner and I have said so.[/color][/color]
>[color=green][color=darkred]
> >> That is very kind but, as I have said elsewhere, I don't think it is
> >> clear all. My function added some special cases for a minute gain in
> >> speed at the cost of a whole lot of lines that could be wrong and
> >> which need checking and testing.[/color][/color]
>[color=green]
> > I will have to withdraw my concession of defeat, unfortunately, and
> > declare victory.[/color]
>
> Fine by me.
>[color=green]
> > I wish I'd thought of it, but Richard Heathfield admits elsethread
> > that the use of memcpy, found in your code and in his, is undefined
> > for overlapping blocks. I looked up memcpy in places other than my
> > lccwin32 documentation and I have discovered this is true for standard
> > ANSI C. If it's been fixed in C99, then the risk exists in all
> > noncompliant compilers.[/color]
>
> No risk at all. I knew this all along and was quite happy with it.
> If you want more from your swap, you have to define what an overlapped
> swap will mean, and we can go round again and look at ways to
> implement this new function.[/color]
I have done so in response to bartc's post above. The "meaning" of an
overlap swap is a human creation, and as human being I have asserted
as a minimal precondition that like a byte swap it shall be reversible
such that swap(swap) is a no-op. Fortunately, as I believe I show in
the response, all you need to do is hop out of the block B when any
byte in block A is in block B.[color=blue]
>
> Of course, you can define it to mean what your code does and then
> you'll have a head start, but I don't see that as either a natural or
> a useful definition of swapping overlapped memory. I'd prefer to
> declare it undefined.[/color]
Try to think a bit more abstractly. After an atomic byte swap A is B
and B is A. After another swap, things are back where they were. This
one-step undoability is the essence of a swap and it needs to be
preserved. My first edition of code didn't preserve this feature: it
deterministically scrambled stuff in an interesting way that doubtless
has a mathematics, but this seems useless.
I think the simplest definition of a vector swap would be "swap all
nonoverlapping zones".
[color=blue]
>[color=green]
> > This confirms my contention re the genuine risks and gotchas in C,
> > which disqualify it as a useful language either for development or
> > teaching CS. More strongly, it confirms my contention that if you
> > attack people like Herb Schildt on the basis not of mathematics and
> > science, but of an aging infantile disorder, you're going to get bit
> > in the ass.[/color]
>
> Who is "you"? I don't feel any bite marks.[/color]
You haven't been guilty of hounding Schildt while either making a
serious error (recommending memcpy() for "speeding up" memswap) or
engaged in fraud (hiding his knowledge of memcpy's being undefined).
Richard Heathfield has, and I am beginning to believe that this is why
I see so many complaints about his behavior here.
[color=blue]
>[color=green]
> > Although I made some clerical errors and in my revision for "speed" a
> > massive error in incrementing ptrToA and ptrToB before the exit to the
> > exchange code, my solution, I now believe, is the best solution.[/color]
>
> I would say the trouble in getting it right suggests you have over
> complicated the code (I think I showed that in my re-write) but
> without any criteria for deciding, you may declare any code you like
> as "best". Personally, I'd use Richard's version. My added switch
> was not intended to make it "better" -- it was to show one could
> reduce the overhead for very small swaps if one needed to.[/color]
Richard's version doesn't work for overlap and mine does. We're not
coding for the Space Shuttle here, and I think interesting results can
be generated from code with clerical errors, and friendly exchanges
can result from actual bugs (such as my bonehead incrementation of the
ptrToA and the ptrToB prior to the break).
Your simplification was rather trivial, if elegant, with all respect.
I haven't had time to test it but I don't think it buys much.
[color=blue]
>[color=green]
> > And I am not amused by Heathfield's conduct in this ng, which is to
> > constantly promote a bad language to the exclusion of other and better
> > paradigms (notably OO) and to trash personalities (such as Schildt)
> > for errors when in fact he has made a significant error in
> > recommending memcpy without remembering, as the C expert here, that it
> > is undefined for overlap.[/color]
>
> Did he? You may be right, but I assumed that overlapped swaps are
> meaningless and one was allowed (for this exercise) to ignore them.[/color]
The difference in the initial versions (prior to and after my
increment bug) was vivid: "my" code handled overlap in an odd but
deterministic way: Richard's code had undefined (and therefore buggy)
behavior. I believe my simple change in response to bartc makes my
code satisfy my thesis that "a swap must be unswappable by the same
swap repeated once".
[color=blue]
>[color=green]
> > "An expert is one who avoids minor errors while sweeping on to the
> > grand fallacy." It complicates the code enormously to test for the
> > different ways in which two memory blocks may overlap (on the left, is
> > the same (because the length is the same for both), on the right).[/color]
>[color=green]
> > Whereas my solution, which I believed and believe to be the BEST[/color]
>
> I don't think I've ever written any code that I'd be able to call the
> BEST. All I can see is compromises and assumptions. What if the[/color]
That sort of talk makes me glad to be out of the computer business.
What seems to be happening is a bureaucratic discussion amongst the
memcpyers of "how we can fix our totally broken and foolish approach"
by "compromising" in order to save face. Nobunny except me seems to
think that it's possible to define a vector swap, and nobunny
(including me, alas) has consulted the literature on this problem. I
will keep looking this evening to see if anybunny has done the latter,
but I think that the hackers here will continue to hack.
[color=blue]
> branch prediction makes the test for equal bytes a loosing one? What[/color]
A "branch prediction" in an optimized RISC machine that broke a simple
for loop would be extraordinarily poor engineering, IMO. Perhaps you
could explain what you mean by "branch prediction"?
[color=blue]
> if memory writes are so expensive that almost any effort to avoid them
> pays off? [/color]
That's what my solution was designed to accomplish. And in nearly all
computers memory writing, especially three tightly coupled operations
that constitute a swap, IS more expensive that comparing bytes read-
only. My code in bartc has an extra test (coded rather stupidly): it
checks for byte A being anywhere inside block B: it needs only check
that the ptrToA is at the start of the b block, since this only
happens once or never.
I'd really like to take the time to write a graphical C Sharp driver
to pound away at all versions for a variety of scenarios that would
submit C command line executions and compare their results, but my
students are coming back from Chinese New Year and this problem isn't
as important as some of my other projects.
[color=blue]
> What if memcpy is so fast on this machine that any code[/color]
[color=blue]
> that avoids it is wasting its time? What if I am not sure who will be
> maintaining the code and I want clarity above all else? How, with all
> these possibilities, can there be a best solution?
>[/color]
You're right, Ben. In the sick and twisted world of C, with its legacy
of compromises and its privatization by compiler vendors, there ARE
all sort of what "ifs". My instinct was to AVOID these by AVOIDING
memcpy() and I was proven right when Heathfield either admitted,
remembered, or perhaps learned (I hope not this alternative) that
"memcpy() is undefined for overlap".
At this point, I have thought-through the overlap issue as regards
swap on a sea-going ferry in the mysterious Orient and methinks my
thinkthrough might also apply to memcpy...not just our swap issue.
Don't copy on overlap: when byte A is inside block B, proceed to the
end of block B (and at this point I believe you don't need to make the
reverse test).
I'm a pretty egoistic person, but I find it hard to believe that the C
team didn't consider this. I have to conclude that when the issue came
up, it was solved with a lameass committee decision to punish
thousands of application programmers for not anticipating overlap, and
this, I contend, was extraordinarily poor practice on their part. And
I hope you are listening, Clive.
The decision to make memcpy() a total frigging Gotcha resembles the
contention that Nuls don't belong in strings, a foolish contention
because it asks for Murphy's Law to put Nuls in strings. Generations
of C programmers have been bit in the butt by memcpy() and this
madness should stop.
[color=blue][color=green]
> > solution in this horseshit language, by definition handles overlap. If
> > block A overlaps B on the left, the exchange of the last overlapping
> > byte is followed by compares which never exit the for. If block A
> > equals B, the for loop spins quickly through both. If block A overlaps
> > on the right, an execution of the for loop for the overlap zone is
> > followed only by the needed moves![/color]
>
> Why is that the right thing to do? If there is an application that
> needs to swap overlapped regions, I'd be surprised if this behaviour is
> what it needs. But I'd be more surprised that such a think exists,
> but this is one of the best places to find out. Is there such a thing?[/color]
Swapping is utterly pointless inside the overlapping region because by
definition the values of the bytes are the same! We need not learn
this from a standards committee!
[color=blue]
>[color=green]
> > "Beauty is truth, and truth, beauty". My instinct, which I failed to
> > justify, was to avoid the nonsense of the library.[/color]
>[color=green]
> > At this point, and pending further evaluation, I think this
> > demonstrates that C blinds the programming soul.[/color]
>
> I think any single language does this. I don't think C is[/color]
You need, perhaps, to get serious about object-oriented languages.
[color=blue]
> particularly blinding. The best programmers will know several very
> different languages. If you know more than C, C can't blind you.[/color]
Here, I agree. But more critically, your first language has to be
something other than C.
[color=blue]
>
>
>
>
>[color=green]
> > I'm a newbie in the
> > sense that I bailed out of C, and was not deceived by what I consider
> > a false expertise.[/color]
>[color=green][color=darkred]
> >> > Richard's code
> >> > runs faster in terms to clock thingies than mine because as it happens
> >> > memcpy is fast in lccwin32. But my code does save some time[/color][/color]
>[color=green][color=darkred]
> >> Compared to what? My initial tests (I don't have time to run the whole set
> >> multiple times -- I did 20 runs for that last posted set) show that it
> >> is a little slower than Malcolm's simple version.[/color][/color]
>[color=green][color=darkred]
> >> > and I
> >> > think it's the most elegant.[/color][/color]
>[color=green][color=darkred]
> >> Now this may sound churlish, but I can't see how you can consider:[/color][/color]
>[color=green][color=darkred]
> >> void spinoza1111_memswap(char *ptrToA,
> >> char *ptrToB,
> >> int intLength)
> >> {
> >> char chrExchange;
> >> char *ptrToAend = ptrToA + intLength;
> >> char *ptrToAwork = ptrToA;
> >> char *ptrToBwork = ptrToB;
> >> while (1)
> >> {
> >> do
> >> {
> >> if (ptrToAwork >= ptrToAend) return;
> >> if (*ptrToAwork != *ptrToBwork) break;
> >> ptrToAwork++; ptrToBwork++;
> >> }
> >> while (1);
> >> chrExchange = *ptrToAwork;
> >> *ptrToAwork = *ptrToBwork;
> >> *ptrToBwork = chrExchange;
> >> ptrToAwork++; ptrToBwork++;[/color][/color]
>[color=green][color=darkred]
> >> }
> >> }[/color][/color]
>[color=green][color=darkred]
> >> To be elegant. Let me say why. You have two loops, both with
> >> constant true conditions so the only times anything but plain looping
> >> occurs is if you return from the top of the inner one (when you have
> >> moved past the end) or if you break out from it.[/color][/color]
>[color=green]
> > The constant true conditions are not evaluated in optimized code. The
> > intent was to be fast, and I sacrificed a little readability.[/color]
>
> You said it was elegant. That is what I was disputing. If you want
> to claim is that it is fast, then you need to show that by timings
> (and you'll need better timing software than your current driver).[/color]
Your rewrite might be faster, but only in the hacky programming sense.
And in a sense, we do need to get this right first by consensing
(horrible word, that) on the meaning of swap and swap overlap. This is
a mathematical problem, so it would be premature to roar off into more
coding. I am just as much an offender in this regard, since I started
this hack-o-rama.
[color=blue]
>
>
>
>
>[color=green]
> > Break is
> > I admit a Go To, but one that is in the sense of my 1976 Computerworld
> > article, virtually structured.[/color]
>[color=green][color=darkred]
> >> You break out from it when the two chars are not the same. You swap
> >> them, advance the two pointers and go back to the inner loop. If they
> >> *are* the same, you just advance the two pointers. You really have
> >> only one loop:[/color][/color]
>[color=green][color=darkred]
> >> do {
> >> if (ptrToAwork >= ptrToAend) return;
> >> if (*ptrToAwork != *ptrToBwork) {
> >> chrExchange = *ptrToAwork;
> >> *ptrToAwork = *ptrToBwork;
> >> *ptrToBwork = chrExchange;
> >> }
> >> ptrToAwork++; ptrToBwork++;
> >> } while (1);[/color][/color]
>[color=green]
> > Nice. But does it save any time?[/color]
>
> Who knows? I was re-writing it to show why I did not think it elegant.[/color]
I like tighter for loops. You've replaced a very small spinner loop
inside of a larger loop with one big loop and since a decent optimiser
will eliminate any header or trailer processing, the final jump back
just has further to go, increasing the risk of a page fault. It is
true, however, that I have one extra jump back. I can justify this, I
believe, by pointing out that the intent (spin until you find
something worth doing) is in a coding-literary sense more obvious in
my code.
[color=blue]
>
>
>
>
>[color=green]
> > It has a smaller memory footprint and
> > like my code avoids overlap problems.[/color]
>[color=green][color=darkred]
> >> Now, a 'do while (1)' with a conditional return (or break) at the top
> >> is really a plain 'while' loop:[/color][/color]
>[color=green][color=darkred]
> >> while (ptrToAwork < ptrToAend) {
> >> if (*ptrToAwork != *ptrToBwork) {
> >> chrExchange = *ptrToAwork;
> >> *ptrToAwork = *ptrToBwork;
> >> *ptrToBwork = chrExchange;
> >> }
> >> ptrToAwork++; ptrToBwork++;
> >> }[/color][/color]
>[color=green][color=darkred]
> >> This expresses the intent of your code much more clearly: while we are
> >> not at the end of the swap region, exchange the characters if the
> >> differ, and advance the two pointers.[/color][/color]
>[color=green]
> > Very nice rewrite.[/color]
>
> Thank you.[/color]
I meant that sincerely despite the fact that I like mine too. At least
you didn't add a memcpy(), or a memcmp(), or a
horribleLibraryProcedureWrittenOnThePlanetBnarg().
[color=blue]
>[color=green]
> > And, we're not hacking desparately at 3:00 in the
> > morning because we "forgot" that memcpy is undefined for overlap! I
> > will try this out for its speed footprint when I have the time.[/color]
>
> The short code may be faster, but that was not the purpose of the
> re-write.[/color]
Call me spinner.[color=blue]
>
> --
> Ben.- Hide quoted text -
>
> - Show quoted text -- Hide quoted text -
>
> - Show quoted text -- Hide quoted text -
>
> - Show quoted text -- Hide quoted text -
>
> - Show quoted text -[/color]