As I posted recently in another thread, I certainly appreciate the intellectual 
challenge etc., etc. of finding the absolute fastest way of performing some 
machine function.

However, I hope you realize that in real life the exact speed of TRT versus 
SRST is going to be dwarfed by the cost of the I/O.

Possibly dwarfed by the cost of the optimized compile ... <g>

The costs of TRT and SRST may vary with the length of the data read, and with 
other activity on the machine (due to cache "sharing").

Integer arithmetic -- converting pointer + length to pointer -- should be 
almost free. I would not base any decision on whether or not one had to convert 
a length to an address or not. 

Charles

-----Original Message-----
From: IBM Mainframe Discussion List [mailto:[email protected]] On Behalf 
Of John McKown
Sent: Monday, February 24, 2014 8:19 AM
To: [email protected]
Subject: Re: Curious observation: lack of a simple optimization in a C program

Again, my thanks to all for the help, which was my fault in not realizing that 
I had used the -o switch instead of the -O switch and so was not having my code 
optimized.

On the off chance that anybody was wondering why I was doing this, it was just 
a test to try to determine the "best" way to see if a C string ended with a \r, 
or carriage return. Why? Because sometimes people here goof up and ftp a 
Windows file to the mainframe, but do it from a UNIX server.
Well, they don't, but we share an NAS box between Windows an Linux servers.
So the file on the z sometimes has an extraneous \r at the very end of the 
line. One good thing this did for me was point out that I was really doing it 
wrong. I found the address of the end of the string using with the code 
"argv[i]+strlen(argv[i])". But the strlen() code generated actually found the 
end of the string using the SRST and then converted that to an integer 
(size_t), which I then converted right back to an address. So I searched and 
found the strchr() routine which can find the terminating null and returns its 
address. Using this function resulted in a TRT in a loop. Which I didn't much 
care for. So I looked at the memchr() function. But it requires a maximum 
length. Now, since I'm looking for a \0. And since a proper C string is \0 
delimited, I _ASSuMEd_ that the string was properly delimited. This allowed me 
to use an arbitrary length for the memchr() call. So I used 0x7fffffff, or 
2GiB. That seems more than large enough to me.

The code is now:

for(i=0; i<argc; i++) {
     if ('\r'==*( (char *) memchr(argv[i],'\0',0x7fffffff)-1)
          *( (char *) memchr(argv[i],'\0',0x7fffffff)-1) = '\0'; }

Of course, this would really be done after the fgets() call. The code generated 
is lovely:

*         if ('\r' == *(findend-1))
          L        r5,(*)uchar*(r2,r1,0)
          LR       r6,r5
          LA       r0,0
          AL       r6,=F'2147483647'
          SRST     r6,r5
          JO       *-4
          BL       @1L13
          LA       r6,0
 @1L13    DS       0H
          AHI      r6,H'-1'
          CLI      (*)uchar(r6,0),13
          BNE      @1L5
*            *(findend-1)='\0';
          MVI      (*)uchar(r6,0),0
 @1L5     DS       0H

where findend is:
#define findend (char *)memchr(argv[i],'\0',0x7fffffff) // for ease to change 
method

I need to cast the (void *) from memchr() to a (char *) in order to subtract 1 
from it. Of course, this can S0C4 if the string is not \0 delimited. Or it 
could possibly corrupt a byte of innocent storage. But this should not happen 
in my planned use since fgets() should return a pointer to a \0 delimited 
string or NULL. And I _will_ check for NULL.



On Sat, Feb 22, 2014 at 11:16 PM, John McKown
<[email protected]>wrote:

> Just for fun, I wrote a very small C program. I compiled it on 
> Linux/Intel using GCC 4.8.2. I then got it compiled on z/OS 1.13. The 
> program is very
> small:
>
> #include <stdlib.h>
> #include <stdio.h>
> #include <string.h>
> #undef strlen
> int main (int argc, char *argv[]) {
>     int i;
>     for(i=0;i<argc;i++) {
>        if ('\r' == *(argv[i]+strlen(argv[i])) )
>           *(argv[i]+strlen(argv[i]))='\0';
>     }
>     return 0;
> }
>
> <snip/>

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions, send email to 
[email protected] with the message: INFO IBM-MAIN

----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to [email protected] with the message: INFO IBM-MAIN

Reply via email to