Roland- Right Said Roland! Nicely worded answer. Just to extend the discussion to another optimization area- Volatile: Just consider this scenario: on -O3 --------\ -------------------------------- while ( counter--) { toggle(switch_1); delay_routine(500); toggle(switch_1); toggle(switch_2); delay_routine(500); toggle(switch_2); toggle(switch_2); delay_routine(1000); toggle(switch_2); } /* The function delay */ void delay_routine(word16 period) { int i, j; for(i=0; i<period; i++) { for(j=0; j<period>>1; j++); } } --------\ -------------------- If the above code is compiled using o3 option, and loaded, the call to delay_routine will not reach there. Choosing the mixed Source/ASM option in the code composer studio one can observe this. Why does this so happen? The reason is that o3 option tells the compiler to optimize for speed. When the compiler sees the delay_routine, it knows that delay is not returning anything. Neither the delay_routine( ), has any executable code, except for NOPs. Knowing this, since the compiler is asked to optimize for speed, it eliminates the call to the delay(). Is that Semantically Correct? Hell, No. But thats Optimized Code! Scenario:2: On -O3 --------\ -------------------- int nice_flag=0; While(1) { while(nice_flag==0); { bad_port = max_16; } sig_proc(nice_in_buffer,coeffs,nice_out_buffer,&delayptr1,iNCoeffs,nice_in_count\ ); nice_flag=0; } --------\ -------------------------------- In this case,the nice_flag has been defined as an integer and is initialized to 0, and is not at all changed in the file. So, the compiler thinks that the value of nice_flag is always 0, and so there is no need to perform the call to sig_proc(). If the nice_flag had been defined as a volatile integer, then since the compiler knows that there is a possibility of this flag value being changed by some other program, it compiles the conditional code in the above part of the program. Hence the call to sig_proc() will be present in the assembled code in this case. The point is that highly optimized compilers provide very little scope for you to assume *normal bahaviour*. -Bhooshan >From: >To: , >Subject: RE: [code-comp] Re: [Fwd: Re: Re: Max Number Of Arguments passed >to function is t maximum 4?] >Date: Tue, 8 Jun 2004 18:51:36 +0200 > >Sorry, Andrew, but Jeff's answer is indeed correct. It seems that you've >never looked at the optimized Assembly that the C compiler produces. With >optimization turned on, local variables get, whenever possible, assigned to >registers whose scope is only as long as the variable is being used. The >register might then be re-assigned to another local variable whose scope >was >irrelevant before. So the start and end of the lifetime for local variables >is determined by the context of your code and not by any semantic. This is >what optimization is all about. You can also take the example of a loop >construct in C. Such a construct will most likely be translated into a >no-overhead loop (via RPT or RPTB instructions). The loop counter for such >a >loop is located in a dedicated register that always counts down, no matter >if your local loop counter is counting up or down. Debugging optimized code >(especially if the code was also built without flag -mn) does only make >sense if one is aware of the debug limitations of optimized code. CCS might >have some bugs, but this one is definitely not one of them. You simply >can't >have your cake and eat it too. Either you want debugable code that runs >semantically correct or you want fast code that will take some shortcuts. > >Just my opinion, >Roland > >-----Original Message----- >From: Andrew Nesterov [mailto:] >Sent: Dienstag, 8. Juni 2004 17:46 >To: >Subject: [code-comp] Re: [Fwd: Re: Re: Max Number Of Arguments passed to >function is t maximum 4?] > > > Date: Mon, 07 Jun 2004 04:06:48 -0500 > > From: Jeff Brower <> > > > > Unless optimization is completely off, you simply cannot expect any > > local variable to be stay consistent inside a function. > >For practical purposes this might be considered as a correct answer, but >semantically this is incorrect. A local variable, unless explicitly changed >or replaced by another local with a smaller scope, stays constant until >control exits the local scope and in this moment the local variable gets >destroyed. > > > I.e. if you > > hold your cursor over a local variable you might see undefined > > results. > >This is the inability of CCS to track a local variable content, which can >be >stored either in a register or pushed on the stack. Sad thing. I would >rather consider it as a bug. > >Rgds, > >Andrew > _________________________________________________________________ Get head-hunted by 10,000 recruiters. http://go.msnserver.com/IN/46246.asp Post your CV on naukri.com today. |
|
RE: Re: [Fwd: Re: Re: Max Number Of Arguments passed to function is t maximum 4?]
Started by ●June 9, 2004
Reply by ●June 9, 20042004-06-09
Hi Everyone, I would just like to add another aspect to this discussion. Remember that the compiler has the option of disabling some optimizations in the Debug mode. And the expectation is that source level debugging is valid only when the program is compiled in debug mode. So maybe Andrew wasn't totally wrong as well. Regards Piyush --- Bhooshan iyer <> wrote: > > Roland- > > Right Said Roland! Nicely worded answer. > > Just to extend the discussion to another > optimization area- Volatile: > > Just consider this scenario: on -O3 > --------\ -------------------------------- > while ( counter--) > { > toggle(switch_1); > delay_routine(500); > toggle(switch_1); > toggle(switch_2); > delay_routine(500); > toggle(switch_2); > toggle(switch_2); > delay_routine(1000); > toggle(switch_2); > } > /* The function delay */ > void delay_routine(word16 period) > { > int i, j; > > for(i=0; i<period; i++) > { > for(j=0; j<period>>1; j++); > } > } > --------\ -------------------- > > If the above code is compiled using o3 option, and > loaded, the call to > delay_routine will not reach there. Choosing the > mixed Source/ASM option in > the code composer studio one can observe this. > > Why does this so happen? > > The reason is that o3 option tells the compiler to > optimize for speed. When > the compiler sees the delay_routine, it knows that > delay is not returning > anything. Neither the delay_routine( ), has any > executable code, except for > NOPs. Knowing this, since the compiler is asked to > optimize for speed, it > eliminates the call to the delay(). > > Is that Semantically Correct? Hell, No. But thats > Optimized Code! > > Scenario:2: On -O3 > --------\ -------------------- > int nice_flag=0; > > While(1) > { > while(nice_flag==0); > { > bad_port = max_16; > } sig_proc(nice_in_buffer,coeffs,nice_out_buffer,&delayptr1,iNCoeffs,nice_in_count\ ); > nice_flag=0; > } --------\ -------------------------------- > > In this case,the nice_flag has been defined as an > integer and is initialized > to 0, and is not at all changed in the file. So, the > compiler thinks that > the value of nice_flag is always 0, and so there is > no need to perform the > call to sig_proc(). > > If the nice_flag had been defined as a volatile > integer, then since the > compiler knows that there is a possibility of this > flag value being changed > by some other program, it compiles the conditional > code in the above part of > the program. Hence the call to sig_proc() will be > present in the assembled > code in this case. > > The point is that highly optimized compilers provide > very little scope for > you to assume *normal bahaviour*. > > -Bhooshan > >From: > >To: , > > >Subject: RE: [code-comp] Re: [Fwd: Re: Re: Max > Number Of Arguments passed > >to function is t maximum 4?] > >Date: Tue, 8 Jun 2004 18:51:36 +0200 > > > >Sorry, Andrew, but Jeff's answer is indeed correct. > It seems that you've > >never looked at the optimized Assembly that the C > compiler produces. With > >optimization turned on, local variables get, > whenever possible, assigned to > >registers whose scope is only as long as the > variable is being used. The > >register might then be re-assigned to another local > variable whose scope > >was > >irrelevant before. So the start and end of the > lifetime for local variables > >is determined by the context of your code and not > by any semantic. This is > >what optimization is all about. You can also take > the example of a loop > >construct in C. Such a construct will most likely > be translated into a > >no-overhead loop (via RPT or RPTB instructions). > The loop counter for such > >a > >loop is located in a dedicated register that always > counts down, no matter > >if your local loop counter is counting up or down. > Debugging optimized code > >(especially if the code was also built without flag > -mn) does only make > >sense if one is aware of the debug limitations of > optimized code. CCS might > >have some bugs, but this one is definitely not one > of them. You simply > >can't > >have your cake and eat it too. Either you want > debugable code that runs > >semantically correct or you want fast code that > will take some shortcuts. > > > >Just my opinion, > >Roland > > > > > > > >-----Original Message----- > >From: Andrew Nesterov > [mailto:] > >Sent: Dienstag, 8. Juni 2004 17:46 > >To: > >Subject: [code-comp] Re: [Fwd: Re: Re: Max Number > Of Arguments passed to > >function is t maximum 4?] > > > > > > > > > Date: Mon, 07 Jun 2004 04:06:48 -0500 > > > From: Jeff Brower <> > > > > > > Unless optimization is completely off, you > simply cannot expect any > > > local variable to be stay consistent inside a > function. > > > >For practical purposes this might be considered as > a correct answer, but > >semantically this is incorrect. A local variable, > unless explicitly changed > >or replaced by another local with a smaller scope, > stays constant until > >control exits the local scope and in this moment > the local variable gets > >destroyed. > > > > > I.e. if you > > > hold your cursor over a local variable you might > see undefined > > > results. > > > >This is the inability of CCS to track a local > variable content, which can > >be > >stored either in a register or pushed on the stack. > Sad thing. I would > >rather consider it as a bug. > > > >Rgds, > > > >Andrew > _________________________________________________________________ > Get head-hunted by 10,000 recruiters. > http://go.msnserver.com/IN/46246.asp > Post your CV on naukri.com today. > > === message truncated === ===== ************************************** And---"A blind Understanding!" Heav'n replied. Piyush Kaul http://www.geocities.com/piyushkaul __________________________________ |
Reply by ●June 9, 20042004-06-09
Piyush- > I would just like to add another aspect to this > discussion. Remember that the compiler has the option > of disabling some optimizations in the Debug mode. And > the expectation is that source level debugging is > valid only when the program is compiled in debug mode. > So maybe Andrew wasn't totally wrong as well. For practical purposes, debug mode (using debug build or subdir) only makes it clear that there MAY be source-related info in the COFF file. Not what kind or how much -- or what level of optimization -- just that the COFF file should be used for internal purposes only. Release mode provides a convenient way of maintaining a separate, "clean" COFF file with no source info that might assist reverse engineering. -Jeff > --- Bhooshan iyer <> wrote: > > > > Roland- > > > > Right Said Roland! Nicely worded answer. > > > > Just to extend the discussion to another > > optimization area- Volatile: > > > > Just consider this scenario: on -O3 > > > --------\ -------------------------------- > > while ( counter--) > > { > > toggle(switch_1); > > delay_routine(500); > > toggle(switch_1); > > toggle(switch_2); > > delay_routine(500); > > toggle(switch_2); > > toggle(switch_2); > > delay_routine(1000); > > toggle(switch_2); > > } > > /* The function delay */ > > void delay_routine(word16 period) > > { > > int i, j; > > > > for(i=0; i<period; i++) > > { > > for(j=0; j<period>>1; j++); > > } > > } > > > --------\ -------------------- > > > > If the above code is compiled using o3 option, and > > loaded, the call to > > delay_routine will not reach there. Choosing the > > mixed Source/ASM option in > > the code composer studio one can observe this. > > > > Why does this so happen? > > > > The reason is that o3 option tells the compiler to > > optimize for speed. When > > the compiler sees the delay_routine, it knows that > > delay is not returning > > anything. Neither the delay_routine( ), has any > > executable code, except for > > NOPs. Knowing this, since the compiler is asked to > > optimize for speed, it > > eliminates the call to the delay(). > > > > Is that Semantically Correct? Hell, No. But thats > > Optimized Code! > > > > Scenario:2: On -O3 > > > --------\ -------------------- > > int nice_flag=0; > > > > While(1) > > { > > while(nice_flag==0); > > { > > bad_port = max_16; > > } > > > > > sig_proc(nice_in_buffer,coeffs,nice_out_buffer,&delayptr1,iNCoeffs,nice_in_count\ ); > > nice_flag=0; > > } > > > > > --------\ -------------------------------- > > > > In this case,the nice_flag has been defined as an > > integer and is initialized > > to 0, and is not at all changed in the file. So, the > > compiler thinks that > > the value of nice_flag is always 0, and so there is > > no need to perform the > > call to sig_proc(). > > > > If the nice_flag had been defined as a volatile > > integer, then since the > > compiler knows that there is a possibility of this > > flag value being changed > > by some other program, it compiles the conditional > > code in the above part of > > the program. Hence the call to sig_proc() will be > > present in the assembled > > code in this case. > > > > The point is that highly optimized compilers provide > > very little scope for > > you to assume *normal bahaviour*. > > > > -Bhooshan > > > > > > >From: > > >To: , > > > > >Subject: RE: [code-comp] Re: [Fwd: Re: Re: Max > > Number Of Arguments passed > > >to function is t maximum 4?] > > >Date: Tue, 8 Jun 2004 18:51:36 +0200 > > > > > >Sorry, Andrew, but Jeff's answer is indeed correct. > > It seems that you've > > >never looked at the optimized Assembly that the C > > compiler produces. With > > >optimization turned on, local variables get, > > whenever possible, assigned to > > >registers whose scope is only as long as the > > variable is being used. The > > >register might then be re-assigned to another local > > variable whose scope > > >was > > >irrelevant before. So the start and end of the > > lifetime for local variables > > >is determined by the context of your code and not > > by any semantic. This is > > >what optimization is all about. You can also take > > the example of a loop > > >construct in C. Such a construct will most likely > > be translated into a > > >no-overhead loop (via RPT or RPTB instructions). > > The loop counter for such > > >a > > >loop is located in a dedicated register that always > > counts down, no matter > > >if your local loop counter is counting up or down. > > Debugging optimized code > > >(especially if the code was also built without flag > > -mn) does only make > > >sense if one is aware of the debug limitations of > > optimized code. CCS might > > >have some bugs, but this one is definitely not one > > of them. You simply > > >can't > > >have your cake and eat it too. Either you want > > debugable code that runs > > >semantically correct or you want fast code that > > will take some shortcuts. > > > > > >Just my opinion, > > >Roland > > > > > > > > > > > >-----Original Message----- > > >From: Andrew Nesterov > > [mailto:] > > >Sent: Dienstag, 8. Juni 2004 17:46 > > >To: > > >Subject: [code-comp] Re: [Fwd: Re: Re: Max Number > > Of Arguments passed to > > >function is t maximum 4?] > > > > > > > > > > > > > Date: Mon, 07 Jun 2004 04:06:48 -0500 > > > > From: Jeff Brower <> > > > > > > > > Unless optimization is completely off, you > > simply cannot expect any > > > > local variable to be stay consistent inside a > > function. > > > > > >For practical purposes this might be considered as > > a correct answer, but > > >semantically this is incorrect. A local variable, > > unless explicitly changed > > >or replaced by another local with a smaller scope, > > stays constant until > > >control exits the local scope and in this moment > > the local variable gets > > >destroyed. > > > > > > > I.e. if you > > > > hold your cursor over a local variable you might > > see undefined > > > > results. > > > > > >This is the inability of CCS to track a local > > variable content, which can > > >be > > >stored either in a register or pushed on the stack. > > Sad thing. I would > > >rather consider it as a bug. > > > > > >Rgds, > > > > > >Andrew |
|
Reply by ●June 9, 20042004-06-09
Piyush, You are talking about the -mn compiler flag (normal optimization with debug) which, when enabled, will trade some optimization features for better debugability. However, this will leave you with code that is not fully optimized, something that you do not want if you are stressed for making that real-time deadline. Also, the C-compiler will still, for instance, translate loop constructs into no-overhead loops, so you can forget about tracing your local loop variables. Andrew expects that optimized code must run semantically correct which is illogical and defeats the purpose of optimization. - Roland -----Original Message----- From: piyush kaul [mailto:] Sent: Mittwoch, 9. Juni 2004 15:50 To: Bhooshan iyer; ; ; Subject: RE: [code-comp] Re: [Fwd: Re: Re: Max Number Of Arguments passed to function is t maximum 4?] Hi Everyone, I would just like to add another aspect to this discussion. Remember that the compiler has the option of disabling some optimizations in the Debug mode. And the expectation is that source level debugging is valid only when the program is compiled in debug mode. So maybe Andrew wasn't totally wrong as well. Regards Piyush --- Bhooshan iyer <> wrote: > > Roland- > > Right Said Roland! Nicely worded answer. > > Just to extend the discussion to another > optimization area- Volatile: > > Just consider this scenario: on -O3 > ---- > while ( counter--) > { > toggle(switch_1); > delay_routine(500); > toggle(switch_1); > toggle(switch_2); > delay_routine(500); > toggle(switch_2); > toggle(switch_2); > delay_routine(1000); > toggle(switch_2); > } > /* The function delay */ > void delay_routine(word16 period) > { > int i, j; > > for(i=0; i<period; i++) > { > for(j=0; j<period>>1; j++); > } > } > ---- ------------------------ > > If the above code is compiled using -o3 option, and > loaded, the call to > delay_routine will not reach there. Choosing the > mixed Source/ASM option in > the code composer studio one can observe this. > > Why does this so happen? > > The reason is that -o3 option tells the compiler to > optimize for speed. When > the compiler sees the delay_routine, it knows that > delay is not returning > anything. Neither the delay_routine( ), has any > executable code, except for > NOPs. Knowing this, since the compiler is asked to > optimize for speed, it > eliminates the call to the delay(). > > Is that Semantically Correct? Hell, No. But thats > Optimized Code! > > Scenario:2: On -O3 > ---- ------------------------ > int nice_flag=0; > > While(1) > { > while(nice_flag==0); > { > bad_port = max_16; > } sig_proc(nice_in_buffer,coeffs,nice_out_buffer,&delayptr1,iNCoeffs,nice_in_c ount); > nice_flag=0; > } ---- > > In this case,the nice_flag has been defined as an > integer and is initialized > to 0, and is not at all changed in the file. So, the > compiler thinks that > the value of nice_flag is always 0, and so there is > no need to perform the > call to sig_proc(). > > If the nice_flag had been defined as a volatile > integer, then since the > compiler knows that there is a possibility of this > flag value being changed > by some other program, it compiles the conditional > code in the above part of > the program. Hence the call to sig_proc() will be > present in the assembled > code in this case. > > The point is that highly optimized compilers provide > very little scope for > you to assume *normal bahaviour*. > > -Bhooshan > >From: > >To: , > > >Subject: RE: [code-comp] Re: [Fwd: Re: Re: Max > Number Of Arguments passed > >to function is t maximum 4?] > >Date: Tue, 8 Jun 2004 18:51:36 +0200 > > > >Sorry, Andrew, but Jeff's answer is indeed correct. > It seems that you've > >never looked at the optimized Assembly that the C > compiler produces. With > >optimization turned on, local variables get, > whenever possible, assigned to > >registers whose scope is only as long as the > variable is being used. The > >register might then be re-assigned to another local > variable whose scope > >was > >irrelevant before. So the start and end of the > lifetime for local variables > >is determined by the context of your code and not > by any semantic. This is > >what optimization is all about. You can also take > the example of a loop > >construct in C. Such a construct will most likely > be translated into a > >no-overhead loop (via RPT or RPTB instructions). > The loop counter for such > >a > >loop is located in a dedicated register that always > counts down, no matter > >if your local loop counter is counting up or down. > Debugging optimized code > >(especially if the code was also built without flag > -mn) does only make > >sense if one is aware of the debug limitations of > optimized code. CCS might > >have some bugs, but this one is definitely not one > of them. You simply > >can't > >have your cake and eat it too. Either you want > debugable code that runs > >semantically correct or you want fast code that > will take some shortcuts. > > > >Just my opinion, > >Roland > > > > > > > >-----Original Message----- > >From: Andrew Nesterov > [mailto:] > >Sent: Dienstag, 8. Juni 2004 17:46 > >To: > >Subject: [code-comp] Re: [Fwd: Re: Re: Max Number > Of Arguments passed to > >function is t maximum 4?] > > > > > > > > > Date: Mon, 07 Jun 2004 04:06:48 -0500 > > > From: Jeff Brower <> > > > > > > Unless optimization is completely off, you > simply cannot expect any > > > local variable to be stay consistent inside a > function. > > > >For practical purposes this might be considered as > a correct answer, but > >semantically this is incorrect. A local variable, > unless explicitly changed > >or replaced by another local with a smaller scope, > stays constant until > >control exits the local scope and in this moment > the local variable gets > >destroyed. > > > > > I.e. if you > > > hold your cursor over a local variable you might > see undefined > > > results. > > > >This is the inability of CCS to track a local > variable content, which can > >be > >stored either in a register or pushed on the stack. > Sad thing. I would > >rather consider it as a bug. > > > >Rgds, > > > >Andrew > |
|
Reply by ●June 9, 20042004-06-09
Roland and Booshan, There was no need to employ numerous examples on how optimizing compilers might interpret a source code, since they are not quite relevant to the original statement that I argued: > Unless optimization is completely off, you simply cannot expect any > local variable to be stay consistent inside a function. I still inclined to follow the standard of C that guarantees any local variable stay consistent within its scope, no matter what kind of optimization was applied. Had it not been so, a code would have have a possibility to execute in an unpredictable manner. Perhaps I did a mistake in the interpretation of the Jeff's statement, since an optimizing compiler might not allocate a local variable right at the point of entering the local scope or it might discard the variable after the last reference to the variable and before the end of the local scope -- actually it does not matter, since my point was that a local variable stays consistent in both optimized or not optimized code, even if a debugger cannot debug the optimized code. Yes, a local variable can be optimized out if there is no more references to it, but when it is referenced it *is* consistent. Let's look closer at your arguments: > From: > With optimization turned on, local variables get, whenever possible, > assigned to registers whose scope is only as long as the variable is > being used. Yes indeed, whenever it is possible (and needed!) a variable can be stored in a register. This storage method does not change the scope of the variable, which would contradict with the C standard. An optimizer does its job, but it does it by *observing* the C standard. > The register might then be re-assigned to another local variable whose > scope was irrelevant before. So the start and end of the lifetime for > local variables is determined by the context of your code and not by > any semantic. That's exactly what I was saying, since semantics is equivalent to context in the context of your clause :) An optimizer might have the liberty to allocate a local variable not right after the beginning of the local scope but at the point the variable was first referenced, which does not conflict with semantics of the code, although it does not follow the standard way of allocating locals on the stack at the point of entering a local scope. This shows only the caveats of debugging an optimized code using the instruments that have been eliminated from the optimized code: debug information. If you work with an assembly code, e.g. stepping through it, or whatever, then keep track on the registers contents, data memory contents, but moving the mouse cursor on a variable in the C source window wouldn't help you much :) The next example: > You can also take the example of a loop construct in C. Such a construct > will most likely be translated into a no-overhead loop (via RPT or RPTB > instructions). The loop counter for such a loop is located in a dedicated > register that always counts down, no matter if your local loop counter is > counting up or down. I am not sure how the RPT loops are connected to local variables, but such a method does not prevent from using a *correct* value of the loop counter inside an RPTB loop. > Debugging optimized code > (especially if the code was also built without flag -mn) does only make > sense if one is aware of the debug limitations of optimized code. I would rather put this as "do not debug an optimized code". Analyse registers and memory. > CCS might have some bugs, but this one is definitely not one of them. I still consider this as a bug, when the compilation mode was "debug info". Debug mode should not complicate simple things. Ok, now I got used to keep track on the values of local variables with paper and pen and do not look at the "locals" window in the CCS :) I have to emphasise that I am talking about "optimization off" and "full symbolic debug" options on. CCS should better off debugging functionality in the release mode. > Either you want debugable code that runs semantically correct or you > want fast code that will take some shortcuts. Shortcuts are fine until they do not violate semantics. Roughly speaking, semantics is the meaning of the code, that is what the code should do. Thus if an optimization violates semantics, this optimization should not be taken. C is not fool-proof at all, and it allows to do something in excess, (like --counter++; when counter is not a volatile), while an optimizer would take care of many of them. For just practical purpuses I'd like to note that the real reason behind optimizing out the call to the delay_routine() function in the example that was presented by Bhooshan, is not exactly what he said: > When the compiler sees the delay_routine, it knows that delay is not > returning anything. Neither the delay_routine( ), has any executable > code, except for NOPs. Knowing this, since the compiler is asked to > optimize for speed, it eliminates the call to the delay(). The fact is the function does have an executable code, and the reason its call has been eliminated is that the function's executable code does not produce any side effects. It is the absence of side effects that makes it possible to get rid of the call. > The point is that highly optimized compilers provide very little scope > for you to assume *normal bahaviour*. Preprocessor warning: "normal behaviour" is underfined :) OK, I think I am done with this. Thanks to all. Andrew > Date: Wed, 09 Jun 2004 07:46:14 +0000 > From: Bhooshan iyer <> > > Roland- > > Right Said Roland! Nicely worded answer. > > Just to extend the discussion to another optimization area- Volatile: > > Just consider this scenario: on -O3 > --------\ -------------------------------- > while ( counter--) > { > toggle(switch_1); > delay_routine(500); > toggle(switch_1); > toggle(switch_2); > delay_routine(500); > toggle(switch_2); > toggle(switch_2); > delay_routine(1000); > toggle(switch_2); > } > /* The function delay */ > void delay_routine(word16 period) > { > int i, j; > > for(i=0; i<period; i++) > { > for(j=0; j<period>>1; j++); > } > } > --------\ -------------------- > > If the above code is compiled using o3 option, and loaded, the call to > delay_routine will not reach there. Choosing the mixed Source/ASM option in > the code composer studio one can observe this. > > Why does this so happen? > > The reason is that o3 option tells the compiler to optimize for speed. When > the compiler sees the delay_routine, it knows that delay is not returning > anything. Neither the delay_routine( ), has any executable code, except for > NOPs. Knowing this, since the compiler is asked to optimize for speed, it > eliminates the call to the delay(). > > Is that Semantically Correct? Hell, No. But thats Optimized Code! > > Scenario:2: On -O3 > --------\ -------------------- > int nice_flag=0; > > While(1) > { > while(nice_flag==0); > { > bad_port = max_16; > } sig_proc(nice_in_buffer,coeffs,nice_out_buffer,&delayptr1,iNCoeffs,nice_in_count\ ); > nice_flag=0; > } --------\ -------------------------------- > > In this case,the nice_flag has been defined as an integer and is initialized > to 0, and is not at all changed in the file. So, the compiler thinks that > the value of nice_flag is always 0, and so there is no need to perform the > call to sig_proc(). > > If the nice_flag had been defined as a volatile integer, then since the > compiler knows that there is a possibility of this flag value being changed > by some other program, it compiles the conditional code in the above part of > the program. Hence the call to sig_proc() will be present in the assembled > code in this case. > > The point is that highly optimized compilers provide very little scope for > you to assume *normal bahaviour*. > > -Bhooshan > >Date: Tue, 8 Jun 2004 18:51:36 +0200 > >From: > > > >Sorry, Andrew, but Jeff's answer is indeed correct. It seems that you've > >never looked at the optimized Assembly that the C compiler produces. With > >optimization turned on, local variables get, whenever possible, assigned to > >registers whose scope is only as long as the variable is being used. The > >register might then be re-assigned to another local variable whose scope > >was > >irrelevant before. So the start and end of the lifetime for local variables > >is determined by the context of your code and not by any semantic. This is > >what optimization is all about. You can also take the example of a loop > >construct in C. Such a construct will most likely be translated into a > >no-overhead loop (via RPT or RPTB instructions). The loop counter for such > >a > >loop is located in a dedicated register that always counts down, no matter > >if your local loop counter is counting up or down. Debugging optimized code > >(especially if the code was also built without flag -mn) does only make > >sense if one is aware of the debug limitations of optimized code. CCS might > >have some bugs, but this one is definitely not one of them. You simply > >can't > >have your cake and eat it too. Either you want debugable code that runs > >semantically correct or you want fast code that will take some shortcuts. > > > >Just my opinion, > >Roland > > > > > > > >-----Original Message----- > >From: Andrew Nesterov [mailto:] > >Sent: Dienstag, 8. Juni 2004 17:46 > >To: > >Subject: [code-comp] Re: [Fwd: Re: Re: Max Number Of Arguments passed to > >function is t maximum 4?] > > > > > > > > > Date: Mon, 07 Jun 2004 04:06:48 -0500 > > > From: Jeff Brower <> > > > > > > Unless optimization is completely off, you simply cannot expect any > > > local variable to be stay consistent inside a function. > > > >For practical purposes this might be considered as a correct answer, but > >semantically this is incorrect. A local variable, unless explicitly changed > >or replaced by another local with a smaller scope, stays constant until > >control exits the local scope and in this moment the local variable gets > >destroyed. > > > > > I.e. if you > > > hold your cursor over a local variable you might see undefined > > > results. > > > >This is the inability of CCS to track a local variable content, which can > >be > >stored either in a register or pushed on the stack. Sad thing. I would > >rather consider it as a bug. > > > >Rgds, > > > >Andrew > |
Reply by ●June 9, 20042004-06-09
> Date: Wed, 9 Jun 2004 17:31:22 +0200 > From: > > Piyush, > You are talking about the -mn compiler flag (normal optimization with debug) > which, when enabled, will trade some optimization features for better > debugability. However, this will leave you with code that is not fully > optimized, something that you do not want if you are stressed for making > that real-time deadline. Also, the C-compiler will still, for instance, > translate loop constructs into no-overhead loops, so you can forget about > tracing your local loop variables. Andrew expects that optimized code must > run semantically correct which is illogical and defeats the purpose of > optimization. Yes, I do expect that an optimized code *is* semantically correct and runs semantically correct. I've never said that it is a good idea to debug an optimized code. The reasons are quite obvious. Once again, the example with no-overhead RPTB loops does not show anything illogical in my reasons. The correct value of the loop variable can be used inside the RPTB loop even if the debugger does not have an information about an optimized loop. There are many types of optimization can be taken, registers can be reused, common subexpressions can be eliminated, local variables can be kept in the registers and modified without being stored back to memory. How does this prove the optimized code "semantically incorrect"? :) Andrew > - Roland |
Reply by ●June 9, 20042004-06-09
Andrew- >Roland and Booshan, > >There was no need to employ numerous examples on how optimizing >compilers might interpret a source code, since they are not quite >relevant to the original statement that I argued: Sorry about that.The examlpes weren't meant as a support for the argument actually(well a little bit!) but primarily as an added information for any new users who might be following this thread.I thought this information might save some people from spending lots of time in debugging optimzed code. > > > Unless optimization is completely off, you simply cannot expect any > > local variable to be stay consistent inside a function. > >I still inclined to follow the standard of C that guarantees any >local variable stay consistent within its scope, no matter what >kind of optimization was applied. Had it not been so, a code >would have have a possibility to execute in an unpredictable >manner. I dont agree with you here. The C standard doesnt actually guarentee that a local variable will *always* stay consistent withing the scope,in fact if that were the case, then there is no need for the standard to define a storage class called *volatile* at all? I think that shd satisfy this line of thinking. A discussion on C standard cannot be never to far away from a discussion on the governor's of the C language-The Compilers. As a programmer if one were just interested in *behavior* then the questioning of optimization doesnt arise at all. But in reality we are not just interested in bahavior(still the foremost concern) but also in the efficiency(trickiest/sleaziest etc...) with which that behavior is achieved. The C standard stops just at defining the behavioral aspects of the language and it leaves the issues of how's to the compiler writer. So, i feel it is incorrect to hold the standard to ransom instead one must look at the standard's through the prisms of the implementational pecularities which the standards themselves acknowledge that they exist. >An optimizer does its job, but it does it by *observing* the C standard. No.It merely *tries* not to alter the promised exterior behavior.Thats it.You are probably talking about what *you* ideally expect from a compiler and not necessarily an observed fact from a test on a sample pool of ten highly-optimizing cross compilers. The C standard is never a defense against an aggressive(even if gone awry) compiler gone bonkers. >I still consider this as a bug, when the compilation mode was "debug >info". Debug mode should not complicate simple things. Ok, now I got >used to keep track on the values of local variables with paper and >pen and do not look at the "locals" window in the CCS :) I have to >emphasise that I am talking about "optimization off" and "full >symbolic debug" options on. This is a bug which am told is fixed in the newer version of CCS(V2.2 and upwards) >Shortcuts are fine until they do not violate semantics. Roughly speaking, >semantics is the meaning of the code, that is what the code should do. >Thus if an optimization violates semantics, this optimization should not >be taken. Again, this is more of a wish than being a reality. In fact if you closely analyze it you will relaize that this argument is not correct. If the compiler writers were to make such decisions on whether or not such optimizations will be attempted at all on the basis of semantics, you will hardly find good aggressive compilers. Is'nt the onus on the programmer who seemingly is interested in much more than behavior which is the only thing that the C standard started out promising? -Bhooshan PS: In fact, it is my opinion that we leave the sanctity and comfort of C's defined behaviors well behind the moment we talk about embedded C programming. _________________________________________________________________ Watch the online reality show Mixed Messages with a friend and enter to win a trip to NY http://www.msnmessenger-download.click-url.com/go/onm00200497ave/direct/01/ |
|
Reply by ●June 9, 20042004-06-09
> Date: Wed, 09 Jun 2004 17:26:47 +0000 > > Andrew- > > >Roland and Booshan, > > > >There was no need to employ numerous examples on how optimizing > >compilers might interpret a source code, since they are not quite > >relevant to the original statement that I argued: > > Sorry about that.The examlpes weren't meant as a support for the argument > actually(well a little bit!) but primarily as an added information for any > new users who might be following this thread.I thought this information > might save some people from spending lots of time in debugging optimzed > code. I'd be happy if we saved just one lost soul... > > > > > Unless optimization is completely off, you simply cannot expect any > > > local variable to be stay consistent inside a function. > > > > I still inclined to follow the standard of C that guarantees any > > local variable stay consistent within its scope, no matter what > > kind of optimization was applied. Had it not been so, a code > > would have have a possibility to execute in an unpredictable > > manner. > > I dont agree with you here. The C standard doesnt actually guarentee that a > local variable will *always* stay consistent withing the scope,in fact if > that were the case, then there is no need for the standard to define a > storage class called *volatile* at all? I think that shd satisfy this line > of thinking. Yes it does guarantee that. A local variable *always* stay consistent within its scope. Had it not been so, what would have changed it? A local variable has local visibility, it is not visible outside its scope. The type qualifier (it does not reserve any storage, so it is not a storage class specifier) volatile is defined by the standard as "the purpose of volatile is to force an implementation to suppress an optimization that could otherwise occur". The standard gives an example of volatile: "For example, for a machine with memory-mapped input/output, a pointer to a device register might be declared as a pointer to volatile, in order to prevent the compiler from removing apparently redundant references through the pointer". As far as I know, the cl6x interprets volatile exactly as the standard does. > A discussion on C standard cannot be never to far away from a discussion on > the governor's of the C language-The Compilers. > > As a programmer if one were just interested in *behavior* then the > questioning of optimization doesnt arise at all. But in reality we are not > just interested in bahavior(still the foremost concern) but also in the > efficiency(trickiest/sleaziest etc...) with which that behavior is achieved. > The C standard stops just at defining the behavioral aspects of the language > and it leaves the issues of how's to the compiler writer. That does not grants a compiler writer with the liberty to deviate from the standard (for whatever reasons) and leave this undocumented. If for some reason a compiler and/or optimizer interpret a code differently than the standard does, it sould be documented. There are different implementations of the language (read this as different compilers) even within the same machine, e.g. for a Pentium (sorry for a stupid example! :). They may exibit different performance for the same C code, but the compiled routines must produce exactly the same results for the integral types or within the machine precision bounds for floating types. > So, i feel it is incorrect to hold the standard to ransom instead one must > look at the standard's through the prisms of the implementational > pecularities which the standards themselves acknowledge that they exist. For what is explicitly marked as "undefined" or "implementation dependent" in the standard, yes. However if the peculiarities kill the standard (change semantics) then I'd better kill the peculiarities! > > An optimizer does its job, but it does it by *observing* the C > > standard. > > No.It merely *tries* not to alter the promised exterior behavior.Thats > it.You are probably talking about what *you* ideally expect from a compiler > and not necessarily an observed fact from a test on a sample pool of ten > highly-optimizing cross compilers. The C standard is never a defense against > an aggressive(even if gone awry) compiler gone bonkers. And if it has been unable not to alter it, than what? Yes, there are a lot of bad programming practices around. Could they be considered as an excuse for neglecting the standard? > >Shortcuts are fine until they do not violate semantics. Roughly speaking, > >semantics is the meaning of the code, that is what the code should do. > >Thus if an optimization violates semantics, this optimization should not > >be taken. > > Again, this is more of a wish than being a reality. In fact if you closely > analyze it you will relaize that this argument is not correct. If the > compiler writers were to make such decisions on whether or not such > optimizations will be attempted at all on the basis of semantics, you will > hardly find good aggressive compilers. There are many things for an optimizer in a more or less complex code, while preserving its semantics. All conformant compilers should work this way. For example, the standard defines that structures are passed to functions by value. This means that the structure gets copied and the function gets its local copy of the structure object. This might be inefficient and as far as I know, cl6x passes structure objects to functions by reference. A function gets a pointer to a stucture object, but this does not mean that if the function modified the object internally the change would stay after the function returned control to the caller. The compiler and optimizer prevent this, and thus keep semantics while perform a certain type of optimization. > Is'nt the onus on the programmer who > seemingly is interested in much more than behavior which is the only thing > that the C standard started out promising? Yeah, shoot the programmer :) > -Bhooshan > > PS: In fact, it is my opinion that we leave the sanctity and comfort of C's > defined behaviors well behind the moment we talk about embedded C > programming. > Fine, but then let's call it an "embedded programming" and omit the "C" as something irrelevant. Or call it "embedded C" or whatever we please, but at this same moment, without a standard, without well-defined rules and behaviour programming would became a black magic, not a technology. I never told that the C is an ideal language. There are other languages, that probably are better choise for computational or control applications than the C, there is always assembly that allows for control of all machine's resorces. Rgds, Andrew |
Reply by ●June 10, 20042004-06-10
Hi Jeff I think you are wrong, as far as "practical purposes" in C6000 compiler is concerned. The primary purpose is still putting symbol table information, but there has another side effect. It would generate an entirely different assembly if debug mode is enabled, and the overall performance would be much less. This is because for full optimization, any line to line correspondence between generated assembler and original source is totally lost, so it would be anyway be impossible to generate proper symbol scope information. Now how much of the optimization is still carried out and how much of it is no done is a question I would like to ask. Maybe it depends only on the judgement of the compiler writer but does it depend on anything else? Any rules? I don't know. Maybe somebody could put some light on it. Regards Piyush --- Jeff Brower <> wrote: > Piyush- > > > I would just like to add another aspect to this > > discussion. Remember that the compiler has the > option > > of disabling some optimizations in the Debug mode. > And > > the expectation is that source level debugging is > > valid only when the program is compiled in debug > mode. > > So maybe Andrew wasn't totally wrong as well. > > For practical purposes, debug mode (using debug > build or subdir) only makes it clear > that there MAY be source-related info in the COFF > file. Not what kind or how much -- > or what level of optimization -- just that the COFF > file should be used for internal > purposes only. > > Release mode provides a convenient way of > maintaining a separate, "clean" COFF file > with no source info that might assist reverse > engineering. > > -Jeff > > > --- Bhooshan iyer <> > wrote: > > > > > > Roland- > > > > > > Right Said Roland! Nicely worded answer. > > > > > > Just to extend the discussion to another > > > optimization area- Volatile: > > > > > > Just consider this scenario: on -O3 > > > > > > --------\ -------------------------------- > > > while ( counter--) > > > { > > > toggle(switch_1); > > > delay_routine(500); > > > toggle(switch_1); > > > toggle(switch_2); > > > delay_routine(500); > > > toggle(switch_2); > > > toggle(switch_2); > > > delay_routine(1000); > > > toggle(switch_2); > > > } > > > /* The function delay */ > > > void delay_routine(word16 period) > > > { > > > int i, j; > > > > > > for(i=0; i<period; i++) > > > { > > > for(j=0; j<period>>1; j++); > > > } > > > } > > > > > > --------\ -------------------- > > > > > > If the above code is compiled using o3 option, > and > > > loaded, the call to > > > delay_routine will not reach there. Choosing the > > > mixed Source/ASM option in > > > the code composer studio one can observe this. > > > > > > Why does this so happen? > > > > > > The reason is that o3 option tells the compiler > to > > > optimize for speed. When > > > the compiler sees the delay_routine, it knows > that > > > delay is not returning > > > anything. Neither the delay_routine( ), has any > > > executable code, except for > > > NOPs. Knowing this, since the compiler is asked > to > > > optimize for speed, it > > > eliminates the call to the delay(). > > > > > > Is that Semantically Correct? Hell, No. But > thats > > > Optimized Code! > > > > > > Scenario:2: On -O3 > > > > > > --------\ -------------------- > > > int nice_flag=0; > > > > > > While(1) > > > { > > > while(nice_flag==0); > > > { > > > bad_port = max_16; > > > } > > > > > > > > > sig_proc(nice_in_buffer,coeffs,nice_out_buffer,&delayptr1,iNCoeffs,nice_in_count\ ); > > > nice_flag=0; > > > } > > > > > > > > > --------\ -------------------------------- > > > > > > In this case,the nice_flag has been defined as > an > > > integer and is initialized > > > to 0, and is not at all changed in the file. So, > the > > > compiler thinks that > > > the value of nice_flag is always 0, and so there > is > > > no need to perform the > > > call to sig_proc(). > > > > > > If the nice_flag had been defined as a volatile > > > integer, then since the > > > compiler knows that there is a possibility of > this > > > flag value being changed > > > by some other program, it compiles the > conditional > > > code in the above part of > > > the program. Hence the call to sig_proc() will > be > > > present in the assembled > > > code in this case. > > > > > > The point is that highly optimized compilers > provide > > > very little scope for > > > you to assume *normal bahaviour*. > > > > > > -Bhooshan > > > > > > > > > >From: > > > >To: , > > > > > > >Subject: RE: [code-comp] Re: [Fwd: Re: Re: Max > > > Number Of Arguments passed > > > >to function is t maximum 4?] > > > >Date: Tue, 8 Jun 2004 18:51:36 +0200 > > > > > > > >Sorry, Andrew, but Jeff's answer is indeed > correct. > > > It seems that you've > > > >never looked at the optimized Assembly that the > C > > > compiler produces. With > > > >optimization turned on, local variables get, > > > whenever possible, assigned to > > > >registers whose scope is only as long as the > > > variable is being used. The > > > >register might then be re-assigned to another > local > > > variable whose scope > > > >was > > > >irrelevant before. So the start and end of the > > > lifetime for local variables > > > >is determined by the context of your code and > not > > > by any semantic. This is > > > >what optimization is all about. You can also > take > > > the example of a loop > > > >construct in C. Such a construct will most > likely > > > be translated into a > > > >no-overhead loop (via RPT or RPTB > instructions). > > > The loop counter for such > > > >a > > > >loop is located in a dedicated register that > always > > > counts down, no matter > > > >if your local loop counter is counting up or > down. > > > Debugging optimized code > > > >(especially if the code was also built without > flag > > > -mn) does only make > > > >sense if one is aware of the debug limitations > of > > > optimized code. CCS might > > > >have some bugs, but this one is definitely not > one > > > of them. You simply > > > >can't > === message truncated === ===== ************************************** And---"A blind Understanding!" Heav'n replied. Piyush Kaul http://www.geocities.com/piyushkaul __________________________________ |
Reply by ●June 10, 20042004-06-10
Piyush- > I think you are wrong, as far as "practical purposes" > in C6000 compiler is concerned. The primary purpose is > still putting symbol table information, but there has > another side effect. It would generate an entirely > different assembly if debug mode is enabled, and the > overall performance would be much less. This is > because for full optimization, any line to line > correspondence between generated assembler and > original source is totally lost, so it would be anyway > be impossible to generate proper symbol scope > information. > Now how much of the optimization is still carried out > and how much of it is no done is a question I would > like to ask. Maybe it depends only on the judgement of > the compiler writer but does it depend on anything > else? Any rules? I don't know. Maybe somebody could > put some light on it. You are right Piyush. I am assuming too much about preferences. Let me just say that I prefer to control debug/optimization explicitly and not count on CCS to make any choices for me. That leads me to use Debug mode for anything that is not releasable to customers, mostly from the point of view of what symbol information is in the .out file. -Jeff > --- Jeff Brower <> wrote: > > Piyush- > > > > > I would just like to add another aspect to this > > > discussion. Remember that the compiler has the > > option > > > of disabling some optimizations in the Debug mode. > > And > > > the expectation is that source level debugging is > > > valid only when the program is compiled in debug > > mode. > > > So maybe Andrew wasn't totally wrong as well. > > > > For practical purposes, debug mode (using debug > > build or subdir) only makes it clear > > that there MAY be source-related info in the COFF > > file. Not what kind or how much -- > > or what level of optimization -- just that the COFF > > file should be used for internal > > purposes only. > > > > Release mode provides a convenient way of > > maintaining a separate, "clean" COFF file > > with no source info that might assist reverse > > engineering. > > > > -Jeff > > > > > --- Bhooshan iyer <> > > wrote: > > > > > > > > Roland- > > > > > > > > Right Said Roland! Nicely worded answer. > > > > > > > > Just to extend the discussion to another > > > > optimization area- Volatile: > > > > > > > > Just consider this scenario: on -O3 > > > > > > > > > > --------\ -------------------------------- > > > > while ( counter--) > > > > { > > > > toggle(switch_1); > > > > delay_routine(500); > > > > toggle(switch_1); > > > > toggle(switch_2); > > > > delay_routine(500); > > > > toggle(switch_2); > > > > toggle(switch_2); > > > > delay_routine(1000); > > > > toggle(switch_2); > > > > } > > > > /* The function delay */ > > > > void delay_routine(word16 period) > > > > { > > > > int i, j; > > > > > > > > for(i=0; i<period; i++) > > > > { > > > > for(j=0; j<period>>1; j++); > > > > } > > > > } > > > > > > > > > > --------\ -------------------- > > > > > > > > If the above code is compiled using o3 option, > > and > > > > loaded, the call to > > > > delay_routine will not reach there. Choosing the > > > > mixed Source/ASM option in > > > > the code composer studio one can observe this. > > > > > > > > Why does this so happen? > > > > > > > > The reason is that o3 option tells the compiler > > to > > > > optimize for speed. When > > > > the compiler sees the delay_routine, it knows > > that > > > > delay is not returning > > > > anything. Neither the delay_routine( ), has any > > > > executable code, except for > > > > NOPs. Knowing this, since the compiler is asked > > to > > > > optimize for speed, it > > > > eliminates the call to the delay(). > > > > > > > > Is that Semantically Correct? Hell, No. But > > thats > > > > Optimized Code! > > > > > > > > Scenario:2: On -O3 > > > > > > > > > > --------\ -------------------- > > > > int nice_flag=0; > > > > > > > > While(1) > > > > { > > > > while(nice_flag==0); > > > > { > > > > bad_port = max_16; > > > > } > > > > > > > > > > > > > > sig_proc(nice_in_buffer,coeffs,nice_out_buffer,&delayptr1,iNCoeffs,nice_in_count\ ); > > > > nice_flag=0; > > > > } > > > > > > > > > > > > > > --------\ -------------------------------- > > > > > > > > In this case,the nice_flag has been defined as > > an > > > > integer and is initialized > > > > to 0, and is not at all changed in the file. So, > > the > > > > compiler thinks that > > > > the value of nice_flag is always 0, and so there > > is > > > > no need to perform the > > > > call to sig_proc(). > > > > > > > > If the nice_flag had been defined as a volatile > > > > integer, then since the > > > > compiler knows that there is a possibility of > > this > > > > flag value being changed > > > > by some other program, it compiles the > > conditional > > > > code in the above part of > > > > the program. Hence the call to sig_proc() will > > be > > > > present in the assembled > > > > code in this case. > > > > > > > > The point is that highly optimized compilers > > provide > > > > very little scope for > > > > you to assume *normal bahaviour*. > > > > > > > > -Bhooshan > > > > > > > > > > > > >From: > > > > >To: , > > > > > > > > >Subject: RE: [code-comp] Re: [Fwd: Re: Re: Max > > > > Number Of Arguments passed > > > > >to function is t maximum 4?] > > > > >Date: Tue, 8 Jun 2004 18:51:36 +0200 > > > > > > > > > >Sorry, Andrew, but Jeff's answer is indeed > > correct. > > > > It seems that you've > > > > >never looked at the optimized Assembly that the > > C > > > > compiler produces. With > > > > >optimization turned on, local variables get, > > > > whenever possible, assigned to > > > > >registers whose scope is only as long as the > > > > variable is being used. The > > > > >register might then be re-assigned to another > > local > > > > variable whose scope > > > > >was > > > > >irrelevant before. So the start and end of the > > > > lifetime for local variables > > > > >is determined by the context of your code and > > not > > > > by any semantic. This is > > > > >what optimization is all about. You can also > > take > > > > the example of a loop > > > > >construct in C. Such a construct will most > > likely > > > > be translated into a > > > > >no-overhead loop (via RPT or RPTB > > instructions). > > > > The loop counter for such > > > > >a > > > > >loop is located in a dedicated register that > > always > > > > counts down, no matter > > > > >if your local loop counter is counting up or > > down. > > > > Debugging optimized code > > > > >(especially if the code was also built without > > flag > > > > -mn) does only make > > > > >sense if one is aware of the debug limitations > > of > > > > optimized code. CCS might > > > > >have some bugs, but this one is definitely not > > one > > > > of them. You simply > > > > >can't > > > === message truncated === > > ===== > ************************************** > And---"A blind Understanding!" Heav'n replied. > > Piyush Kaul > http://www.geocities.com/piyushkaul |