Q:

PERFORM THRU VARYING : exact behavior?

I am trying to understand the behavior of a COBOL program and I am stumbling upon the following lines:
PERFORM  525-NUMERIC    THRU  525-EXIT                       
    VARYING K FROM 1  BY 1   UNTIL  K > CAR-L.         

I understand the global concept that it is some kind of loop based on the value of K, but I fail to understand the impact of the THRU  525-EXIT words?

A:

A PERFORM can execute a range of paragraphs or SECTIONS serially. This is done by using THRU/THROUGH to name the last paragraph/SECTION of the series, the PERFORM having already named the starting point.
A simple PERFORM of a paragraph:
       PERFORM                      10-OPEN-INPUT-FILES

This establishes a "range" for the PERFORM starting with 10-OPEN-INPUT-FILES and ending with the last statement of that paragraph.
A PERFORM of multiple paragraphs, one after the other:
       PERFORM                      10-OPEN-INPUT-FILES
         THRU                       10-OPEN-INPUT-FILES-EXIT

This establishes a wider range for the PERFORM, starting from 10-OPEN-INPUT-FILES and ending with the last statement of 10-OPEN-INPUT-FILES-EXIT.
This isn't really a good or useful thing, but it gets used a lot in a specific way, and that is perhaps what you have. This is to have an "exit paragraph" associated with each paragraph that is PERFORMed. One original paragraph, followed by one unique exit-paragraph associated (by the second paragraph's position, nothing else) with that original paragraph.
This is never necessary, programs work fine without them. However, since there is an "exit-paragraph" of course there is now a label which can be the target of a GO TO. Code something stupid, or come across something already coded that way, and just jam a GO TO in to get you (but perhaps not the next person) out of trouble. This is not a good thing to do, although it will often be seen as "expedient". And the next time in the same code the expedient route will be taken, and the next time, and then something which should always have been simple has become... complex.
Stunningly (my opinion, for many this is normal practice), more than a few sites have it in their local standards that an exit-paragraph must be included for each PERFORMed paragraph and PERFORM ...  THRU ... must be coded.
As well as asking for trouble by inviting the use of GO TO, another problem is that the physical location of the code is now relevant. If you put a new paragraph before the exit-paragraph, then it becomes part of the PERFORM range, whether intended or not. Some people intend, even going so far as to code several paragraphs to be within the range of a PERFORM, with the ever-handy GO TO as their "get out of mess" tool.
A further problem is that when you encounter the PERFORM ... with THRU ... you don't know how many paragraphs (or SECTIONS) are included in the PERFORM without looking at the paragraphs (or SECTIONS) themselves.
You can also PERFORM a SECTION. This is a procedure label followed by the word SECTION and terminated by a full-stop/period.
A SECTION can contain paragraphs. When you PERFORM a SECTION, all paragraphs in the SECTION are within the PERFORM range, until the last statement of the SECTION. It is like a PERFORM ... THRU ... without the THRU ... bit. It has the same problems as the PERFORM ... THRU ... plus the additional one that if unique paragraphs are used as the target of a GO TO, great care must be taken if a SECTION is copied to make a new one. It is perfectly legal to GO TO out of a SECTION (or paragraph) but this would usually be unintended and can cause chaos, as program control wanders of somewhere else. If using a GO TO to an exit-paragraph in a SECTION, the best thing to do is to use identical names for the exit-paragraph. Any GO TO within a SECTION will be automatically "qualified" by the compiler to the paragraph within that SECTION (if there are non-unique paragraph-names referenced in a SECTION, but no paragraph of that name in the SECTION itself, the compiler will spot the error).
With your code, locate the paragraph being PERFORMed, and search sequentially for the paragraph named on the THRU. It is probably just a dumb exit (a paragraph with just an EXIT statement and a full-stop/period). There may be other paragraphs in between those two, if you are very unlucky. Any such paragraphs are included within the range of the PERFOR, without being explicit on the PERFORM statement. The
It is worth noting that the EXIT statement itself does nothing. It is a "No Operation" or NOP (or NOOP). At the end of a paragraph which is PERFORMed a number of instructions will be generated to do the exit-processing, this is automatic and does not (and never has) relied on the presence of an EXIT statement.
It used to be the case, prior to the 1985 Standard, that EXIT had to be coded in a paragraph on its own. This is no longer the case. You can fill a paragraph with EXIT statements (say 20) and then finish the paragraph with a DISPLAY. PERFORM the paragraph, and you will see the DISPLAY output.
A paragraph which is PERFORMed without a THRU should not contain a GO TO. It is not a compile-error if it does contain a GO TO. It is an accident waiting to happen. 
People who feel the need to use GO TO have to use PERFORM ... THRU ... or to use a PERFORM of a SECTION. Unfortunately, even if the original coder does not use GO TO, the use of PERFORM ... THRU ... or PERFORM of a SECTION does make it easy for someone in the future to use GO TO. If there is somewhere for a GO TO to go to, then it is more likely that a GO TO will appear at some point. If there is no existing target for a GO TO, then the next coder will be put off from using GO TO by having to make additional changes.
In the current Standard, from 2014, there are some new versions of EXIT. (The EXIT PROGRAM version of EXIT has been around a long time already, although these days the IBM-inspired GOBACK is more likely to be used to return to the CALLing program).
The new possibilities include EXIT PARAGRAPH and EXIT SECTION. Check the documentation for your compiler to see what variants of EXIT are available. All the variants of EXIT generate executable code, it is just the plain EXIT which does not.
If your compiler does allow EXIT PARAGRAPH and EXIT SECTION, it means you no longer need to have a label to allow use of a (now "secret") GO TO, it just won't be called GO TO, it'll be called EXIT somevariant. Just remember that all those (except EXIT PROGRAM) are GO TOs in disguise, and that code can always be rearranged (and often simplified) to obviate the need for GO TO.
It does require experience to structure for no-GO TO code, so don't be too concerned with it for now. If your site uses GO TO (implied by the use of THRU) then it will be very important that you understand the ramifications of the use of GO TO because existing code will use it. 
Then start in a small way to avoid GO TO yourself, increasing the scope of your efforts as you become familiar with techniques to do so. Remember, the aim is to simplify the code, or at least not make it worse, not just to not code GO TO by rote. If you make your code complicated simply to avoid a GO TO, then use GO TO until you know how to do it better.
Many, many, good and experienced COBOL programmers write understandable programs using GO TO. Unfortunately the majority of programmers are not "good and experienced" so are happy to short-circuit something with GO TO and move on.
The VARYING on a PERFORM is a means to repeat the execution, with a starting point, an increment and termination condition. This is the same whether or not THRU is coded.

An example of what can happen with an errant GO TO going outside the range of a PERFORM can be found here: https://codegolf.stackexchange.com/a/20889/16411. That is coded with SECTIONs but it could equally be done with PERFORM ... TRHU ...

Very good to read this in conjunction with Bruce Martin's answer.

A:

Following on on from Bill's answer, I will try and add a more visual answer. 
         Perform Proc-A thru Proc-D.
         ...

     Proc-A. 
        ....

     Proc-B.
        ....

     Proc-C.
        ....

     Proc-D.
        ....

In the above, the Perform Proc-A thru Proc-D executes procedure's Proc-A, Proc-B, Proc-C and Proc-D. It is a shorthand for
     Perform Proc-A
     Perform Proc-B
     Perform Proc-C
     Perform Proc-D

The Perform Thru syntax has several problems:

It is not always clear what is being executed. 
 Perform B100-Load-From-DB thru B500-Save-To-Db

I think the following tells you more
 Perform B100-Load-From-DB
 Perform B200-Adjust-Stock-for-Purchases
 Perform B300-Adjust-Stock-for-Sales
 Perform B400-Calculate-Markdowns
 Perform B500-Save-To-Db

It makes it easy to introduce problems i.e. if you add a procedure in the wrong position, you will be introducing code without realizing it
 Proc-B.
    ....

 Proc-in-wrong-position.
    ....

 Proc-C.
    ....

An error like the above is easy to make but hard to spot
It is one of those Cobol features that Seemed like a good idea at the time it was introduced; but should be avoided !!!

A:

Expounding on both Bill's and Bruce's excellent answers.
Starting with code from Bruce's example.
    Perform B100-Load-From-DB thru B500-Save-To-Db
...
B100-Load-From-DB
...
B200-Adjust-Stock-for-Purchases
...
B300-Adjust-Stock-for-Sales
...
Some-Danged-Ol-Thing
...
B400-Calculate-Markdowns
...
B500-Save-To-Db

This still seems reasonably simple enough.  Code in each paragraph will be processed in top down order: B100-Load-From-DB, B200-Adjust-Stock-for-Purchases, B300-Adjust-Stock-for-Sales, Some-Danged-Ol-Thing, B400-Calculate-Markdowns, B500-Save-To-Db
As Bill indicated, the addition of GO TO statements to a PERFORM ... THRU block introduces the author of said code to a special quadrant in the Ninth Circle of Hell.
    Perform B100-Load-From-DB thru B500-Save-To-Db
...
B100-Load-From-DB
...
    GO TO B400-Calculate-Markdowns
...
B200-Adjust-Stock-for-Purchases
...
B300-Adjust-Stock-for-Sales
...
    GO TO B200-Adjust-Stock-for-Purchases
...
Some-Danged-Ol-Thing
...
B400-Calculate-Markdowns
...
B500-Save-To-Db

The Hell is exacerbated by yet more "clever thinking" when someone decides to run a portion of the PERFORM ... THRU block.
    Perform B200-Adjust-Stock-for-Purchases thru B300-Adjust-Stock-for-Sales
...
    Perform B100-Load-From-DB thru B200-Adjust-Stock-for-Purchases
...
    Perform B100-Load-From-DB thru Some-Danged-Ol-Thing

There are numerous opportunities to fall through the Looking Glass and continue on into several Alternate Realities.  I'm not just pontificating about theoretical possibilities.  I'm talking actual experiences in code I've had over the years.
Whilst I was growing up, er I mean learning to code in COBOL, I was all but threatened with being beaten by a large man with a rattan stick if I stepped outta line.  As such, I know how to walk on the edge of the precipice and use PERFORM ... THRU with GO TO interspersed throughout and not fall off the edge of the world.  However, it makes for very dangerous code that can kill, so more importantly I know how to de-fang code like this and turn it into something civilized.

