One stupid question concerning IFs and GOTOs.

One stupid question concerning IFs and GOTOs.

I wonder if exists any way to translate this assembler similar fortran code into the modern code without IF-THEN-ELSE? How to minimize the interminable conditional constructs? If my question is very stupid, forgive me. Just too many IFs and GOTOs spoil the soup.

22 Beiträge / 0 neu
Letzter Beitrag
Nähere Informationen zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.

The top line of your code snip was clipped. Also it is unclear as to if some or all of the tested variables can only have 0 or 1.

For the binary variables (possbly A:F) consider compositing them into an integer, use the integer as an index into a (parameter) table, then use the contents of the table either in your IF test or in a computed GOTO.

Jim Dempsey

www.quickthreadprogramming.com

Hmm… There is not a full stroke in the top line … The following line shows the full stroke:

 IF(A.EQ.0.AND.B.EQ.0.AND.C.EQ.0.AND.D.EQ.0.AND.E.EQ.0.AND.F.EQ.1) GO TO 9

Are the values only 0 or 1? Could you use LOGICAL instead?

Steve - Intel Developer Support

I am thinking about LOGICAL…
In theory – only 0 and 1, in practice – nobody knows.

In other words a program has to use only 0 and 1. No other numbers are expected.

If efficiency is the goal, it's not a foregone conclusion that streamlining the source code will make it run faster than a good compiler can do.

It looks like some kind of automatically generated code.  If the goal is to change this code into something more human readable, both open source and commercial tools exist (e.g. http://www.polyhedron.com/spag0html )  It's likely to require iterations between manual improvement, testing, and automated beautifier.

I like Jim's idea of a table. It would be useful to draw up a table of all the combinations (there will be 256 of them for A through H) and determine where you want each one to go.

Steve - Intel Developer Support

There 1 test to start for goto 9 and then 6 test for goto 6 follow. You need to negate them eg. if(h.lt.0 .or. h.gt.1 ) goto 6  or if( .not. (h.eq.o or. h.eq.1))  goto 6 and then it all look much clearer with no cascading jumps (if clarity is the objective).

Holy Mackerel! 256! Steve! Could you show it by example? I think you can not.
I like Tim’s idea about changing this code into something more human readable by means of special tools.
Without doubt the efficiency is of importance for my tasks, but from time to time somebody should read the code, it will not be a good thing to see many GOTOs that jump like fleas.
The reasonable balance is wanted.

4 app4619
Thank you! Your notice is very useful.

Sorry, it's 512 possible combinations. You have nine variables, 2**9 is 512.

Steve - Intel Developer Support

Of course, I should express my grateful to Jim. Otherwise nobody could have read Steve’s comments. His remarks were dripping with mild sarcasm. Jim’s idea, gently ridiculed by Steve, was yet believed by some.

4 Steve. It’s a part of code. In fact a number of variables are more than 90. But it’s a top secret. Nobody should know about it. Only you and me.

Um, I did not mean to ridicule Jim at all, and no sarcasm was intended. If the only values allowed were truly 0 and 1, and if the number of variables was limited to what you showed, then a table was a fine and efficient idea. But now you tell us that the real code is quite different, so our advice is no longer relevant.

At this point, my advice would be to leave it alone. Add some comments if you wish, but if you try to simplify it you'll probably end up breaking it.

Steve - Intel Developer Support

The code originally shown includes lines such as

IF(N.EQ.0.OR.N.EQ.1)GOTO xxx
If N were truly a boolean variable, this test would not make sense -- why test if a boolean variable has one of the only two possible values that it can have? Steve's advice to leave things alone is sound, given that the "atru" may not know the range of allowable values of M, N, etc.

The not broken don't fix principal is a good one most of the time with software. If you make a change to improve the readability the principal of 'assume nothing' is a good one unless you really understand everything the code does. As per my suggestion a few posts back you can improve the readability enormousy without changing the sequence or underlying logic by taking the negative (.not.) case of many of the checks to remove much uncessessary bunny hopping with goto's. 

atru are you looking for something like this?

IF (.NOT.(A.EQ.0.AND....)) THEN
IF(.NOT.(H.EQ.0.OR.H.EQ.1).OR.
.NOT.(N.EQ.0.OR.N.EQ.1).OR.
.NOT.(M.EQ.0.OR.M.EQ.1).OR.
.NOT.(F.EQ.0).OR. ! Same as F.NE.0
(.NOT.(B.EQ.1.AND.A.EQ.0).AND.
.NOT.(B.EQ.0.AND.A.EQ.1)).OR.
(.NOT.(E.EQ.1.AND.D.EQ.0.AND.C.EQ.0).AND.
.NOT.(E.EQ.0.AND.D.EQ.1.AND.C.EQ.0).AND.
.NOT.(E.EQ.0.AND.D.EQ.0.AND.C.EQ.1))) THEN
WRITE (*,*) ...
ENDIF
8 ....
ENDIF
9 ....

If all values can only be positive you can use to the following

IF (A+B+C+D+E.NE.0.OR.F.NE.1) THEN
IF(H.GT.1.OR.
N.GT.1.OR.
M.GT.1.OR.
F.NE.0.OR.
A+B.NE.1).OR.
C+D+E.NE.1) THEN
WRITE (*,*) ...
ENDIF
8 ...
ENDIF
9 ...

Sorry, I tried to enable syntax highlighting, but I'm to stupid to paste and handle rich-text.

Are the variables integers?
Are they definitely initialised to some value somewhere?

Are they restricted to values of 0 or 1?

If the latter, then statements 4 and 5 can be replaced with

IF(A+B.EQ.1) go to 5

IF(C+D+E.EQ.1) go to 8

If values other than 0 and 1 are permitted, leave it alone and don't break the code!
Suppose the variables are initialised to = -1, then the additions above will not duplicate the code you show.
And anyway, someone has pointed out that testing a variable for equality to 0 OR 1 indicates other values are possible, otherwise
the test is pointless.

H, M, N appear to have more than two values. These appear to have at least three states: 0, 1, anything else. For this section of code, 0 or 1 are valid, anything else is invalid (goto 6).

This would work, but it isn't any clearer:

  IOR_BITS = IOR(A,IOR(B,IOR(C,IOR(D,E))))
  IF(IOR_BITS.EQ.0.AND.F.EQ.1) GO TO 9 ! All 0, F==1
  IF(F.EQ.1) GO TO 6
  IF(IAND(IOR_BITS,-2) .NE. 0) GO TO 6 ! Any not 0 nor 1
  IF(IAND(IOR(N,M),-2) .NE. 0) GO TO 6 ! Any not 0 nor 1
  IF(IXOR(A,B).EQ.0) GO TO 6 ! Both 0 or both 1
  IF(C+D+E.EQ.1) GO TO 8
6 WRITE(*,*)

Jim Dempsey

www.quickthreadprogramming.com

Steve! Please forgive me. I did not want to offend anybody.
Having thought over all comments I decided that Jim’s idea was very interesting. But your support of it - was not properly understood.
Nevertheless your advice is still relevant because all code will be probably transformed into the blocks. So, Jim’s idea is still alive.
2**9 + 2**9 + 2**9…

mecej4
Thank you! 0 and 1. The other numbers can appear as a result of human factor or improper calculation.

app4619
Your idea to make “negative” is very good. Thank you again!

rwg
Yes. I am looking for something like that.
All values are both positive and integers.
Your idea of summation is brilliant. Thank you!

Anthony Richards
All variables are integers.
Answer to second question – yes.
Only 0 or 1.
I like idea of summation.
The values other than 0 and 1 are not expected but they can appear as a result of improper calculation.

Thank you Jim! I have never used IOR and IAND. It looks like something fresh for me. It’s very good.

Kommentar hinterlassen

Bitte anmelden, um einen Kommentar hinzuzufügen. Sie sind noch nicht Mitglied? Jetzt teilnehmen