T.R | Title | User | Personal Name | Date | Lines |
---|
447.1 | | BMT::KOZAKIEWICZ | | Wed Apr 15 1987 22:07 | 39 |
| I am not sure if this applies to you, since I cannot tell from your
note, but an absolute sure fire way to get the error you describe
is if the character after the last valid character in the filename
string is not = 0 (NUL) or 32 (SPACE). This can easily happen if
you are reading the file specification into a BYTE array, or you
are using a CHARACTER variable for other things and are not careful
to blank it before you use it for a filename. Your code should look
like this:
BYTE FNAME(40)
.
.
READ (UNIT, '(Q,40A1)') LEN, FNAME !Get filename and length
FNAME(LEN+1) = 0
OPEN (UNIT=ZZ, NAME=FNAME, ....)
If you are using a CHARACTER variable, the following will get
you into trouble:
CHARACTER*80 BUF
.
.
READ (UNIT, '(A80)') BUF !Read some junk into BUF (I
! assume it has control characters
! in it)
other processing occurs
READ (UNIT, '(A15)') BUF(1:15) !Assume fixed length filename?
OPEN (UNIT, NAME=BUF...) !BUF(16:16) may contain junk
! from before...
The proper way to do this is:
BUF = ' '
READ (UNIT, '(A80)') BUF
OPEN (UNIT, NAME=BUF...)
|
447.2 | I hacked around it... | PHENIX::SMITH | William P.N. (WOOKIE::) Smith | Thu Apr 16 1987 13:59 | 18 |
| Well, I can read the first couple of lines out of one file, read
the first couple of lines out of a different file, [and on and on
all day if I like], but as soon as I decide I like a file and read
all the data out of it, I can't even open the same file again!
I have been clearing the string to spaces before requesting another
file name, but that doesn't seem to make much difference.
I did, however, find a work around. If I clear out the comment
lines that I read from the file before I close it and then go back
and open another file, it works just fine. [Well, this is the hackers
notes files... :} ] Don't ask me why RMS cares what I do with other
variables, but whatever makes it happy! I've commented it so that
no-one will try to 'enhance' the code by removing that extra little
addition....
FORTRAN: GOD is real, unless declared integer....
Willie
|
447.3 | | BISTRO::HEIN | If We don't Have it,You don't Need it! | Tue Apr 21 1987 04:24 | 20 |
| William,
I expect that the reply in .1 really explains the problem.
Somehow there is garbage in the file name string. As you
found the clearing this 'comment line' appears to fix the
problem the conclusion must be that there is somehow an
overlap of the variable and the one used for the filename.
To verify I would change to OPEN statement to use a USEROPEN
of the simplest sort and set a breakpoint there. When the
useropen is called after displaying an entire file and trying
to open a second file, then look in the FAB filename fields:
@4(AP) --> Fab
Fab + 2C --> File name address
Fab + 34 --> File name size (byte)
Fab + 30 --> Default name addres
Fab + 35 --> Default name size (byte)
Have fun,
Hein.
|
447.4 | reminiscing ... | ANGORA::ZARLENGA | Spock, where's my mint julep? | Thu Apr 23 1987 19:58 | 14 |
| 1 more idea - check the filename CLOSELY. I found an obscure
error in a program on a VT220 while my VT125 was being serviced.
The filename string's 1st character had bit 7 set ... it was a
"multinational" character ... my VT125 displayed it the same
whether bit 7 was 0 or 1 ... the VT220 displayed a strange looking
creature.
I though I had all bases covered ... I was writing the filename
to the terminal ... but as characters, when I went to write the
individual cells as octal numbers the error showed up on my VT125
too. That was the toughest one I've ever found (and it was my
code too!)
It might be similar to your problem.
-mike
|
447.5 | got it! | PHENIX::SMITH | William P.N. (WOOKIE::) Smith | Thu Apr 23 1987 20:30 | 15 |
| Thanks guys, I found it, I had set the filename to all spaces before
I got the new name from the terminal, but I had not stuck in a zero
byte for a terminator. Works just fine now.
READ (*,1000) NUMCHAR, INFILE
1000 FORMAT (Q,50A1)
IF (NUMCHAR.LT.50) INFILE(NUMCHAR+1) = 0
I also made the file name up to 50 chars long, so I can use the
new VMS sytle of very_long_file_names_so_they_wont_conflict.and_
I_dont_accidently_delete_them.
Willie
|
447.6 | Fortran speed? | COBRA::SMITH | William P.N. (WOOKIE::) Smith | Mon Apr 27 1987 14:05 | 26 |
| OK, since it's part of the same project, I'll continue on instead
of starting a new topic. I've written a quick and dirty Fortran
program to read lines out of a text file and proccess tham as follows:
If the line you read is the same as the last line, throw it
away and go back for another one.
If the line is different and there is a " in it (it contains
text) write it to the output file.
If the line is different and does not contain a " (no text),
squeeze all spaces out of it and write the result to the output
file.
This has the effect of making the file up to 73 percent smaller,
and works really well except for one minor detail. It takes just
short of forever. On a microvax I it took around 14 minutes of
real time, almost 14 minutes of CPU time, and under 100 page faults
to squish a 507 block file down to 160 blocks. I figgered there
was something wrong, so I tried it on a machovax and it still took
7 minutes, mostly CPU time. Is this reasonable? The source is
only 4 blocks with comments....
Willie
14 minutes of CPU time
|
447.7 | | ALBANY::KOZAKIEWICZ | You can call me Al... | Mon Apr 27 1987 16:32 | 18 |
| I see two possibilities. The first (and least likely) is that your files
are assumed to be shared, and thus RMS is performing 1 disk I/O (with the
attendant record blocking/unblocking) per record operation. This can be
solved by either ensuring that there is no implied file sharing going on,
or by using the deferred write option (I have sample FORTRAN programs which
enable this option, if you need to see them),i.e. set the FAB$V_DFW bit.
The other (most likely) possibility is the amount of time consumed comparing
the character strings. Are you using CHARACTER variables or BYTE arrays?
If you are using BYTE arrays and comparing each character in a DO loop,
processing will be slow. Direct comparisons via CHARACTER variables *MAY*
be faster (I do not know how FORTRAN handles them - get a machine code listing
and see...). One algorithm change you might make would be to
compare the length of the strings first (assuming these are variable length
records...). Only compare the strings if the length is the same (If the length
is different, so are the strings). Also, combine several of the operations
into one loop. That way you could compare and check for '"' at the same time.
|
447.8 | I'll see what happens. | COBRA::SMITH | William P.N. (WOOKIE::) Smith | Mon Apr 27 1987 17:39 | 8 |
| I'm using byte arrays, I'll give CHARACTER arrays a shot. I'm already
comparing string length, but I'm not doing the _look_for_"_while_
_squishing_string_, which should speed things up a bit (and save
me another few bytes), I'll let you know what happens. Never heard
of deferred write, I'd appreciate your samples... Thanks,
Willie
|
447.9 | | CAFEIN::PFAU | Now where did I leave my marbles? | Mon Apr 27 1987 18:02 | 6 |
| I believe (my FORTRAN is a bit rusty) that VAX-FORTRAN has an INDEX
function which will return the offset into a string at which a
particular character or substring appears. You might want to use
this to locate the quote character.
tom_p
|
447.10 | Check BAS$EDIT functionality. | BISTRO::HEIN | If We don't Have it,You don't Need it! | Tue Apr 28 1987 05:00 | 1 |
|
|
447.11 | use PCA first | DYO780::DYSERT | Barry Dysert | Tue Apr 28 1987 09:55 | 8 |
| It's true that there is an INDEX function that allows you to find
a character within a given string. What I would suggest you do
first, though, is load your program with PCA. PCA is a wonderful
product that allows you to find where your program is spending most
of its time. After all, you may be grinding to optimize what you
think is the "bad" code only to realize a few percent performance
improvement. PCA will show you for sure what part of your program
is responsible for the excessive CPU time.
|
447.12 | Now if it had been Z-80 assembly... | COBRA::SMITH | William P.N. (WOOKIE::) Smith | Tue Apr 28 1987 14:06 | 9 |
| Well, I asked a Real Programmer for hints and he ended up rewriting
the code and now it runs in 2 minutes... The most significant speed
increases were opening the files (...,blocksize=20480,...), using
character arrays instead of bytes, and combining short output lines
into longer ones. The logic is pretty much the same as my original
program, but the coding is _very_ different....
Willie
|
447.13 | | ALBANY::KOZAKIEWICZ | You can call me Al... | Tue Apr 28 1987 14:19 | 40 |
| I checked out what kind of code the FORTRAN compiler generates for the
following two character compare sequences:
CHARACTER*99 A,B
IF (A .NE. B) GOTO 999
and
BYTE A(99),B(99)
DO I = 1, 99
IF (A(I) .NE. B(I)) GOTO 999
ENDDO
In the first example the compiler yields something like:
MOVAL A, reg a ;Move the addresses of the strings to
MOVAL B, reg b ; registers
CMPC3 99, A, B ;Compare...
BNE #.999 ;NE
By the way, the CMPC instruction is not defined for the uVAX architecture.
The second example gets you something like this:
MOVAL A, reg a
MOVAL B, reg b
MOVL #-99, R0 ;Loop counter
10$: CMPB (Ra)+, (Rb)+ ;Compare this byte
BNE #.999 ; NE
AOBLEQ R0, 10$ ;Loop
As you can see, the second example replaces one instruction (CMPC3) with
three (CMPB, BNE, AOBLEQ) which must be executed once for each equal character.
Of course, the character compare instruction will vary in execution time
depending upon the length of the longest string, by I will lay money that
it executes faster than the DO loop.
And by the way, the performance coverage analyzer (PCA) might help, but it
is really going after a fly with a cannon. The use of such tools is not
a panacea for poor design.
|