Page 1 of 1

slow processing

Posted: Thu Sep 27, 2018 6:58 am
by Tebron
Hi,

I have a problem with this part of code:

if(win_max_alrm==10){
counter++;
}

It is a part of a larger code and when i run it, a process time is 35ms, BUT if i comment a counter++; command then a process time is 4ms. And it is independent that the if is true or false.
What can cause this type of issue?

Thanks for answers

Re: slow processing

Posted: Thu Sep 27, 2018 8:31 am
by jcsbanks
The whole thing is likely optimised out when commented.

Task switching too.

Need more context.

Re: slow processing

Posted: Thu Sep 27, 2018 10:21 am
by Tebron
I use 4 task, 3 of them running on CPU0 the last on the CPU1. This is the problematic task.

Code: Select all

while(1){
if(statement)    //~every 100ms
for(0-80){
     for(0-60){
          for(0-var){
             if(statement)
                var++
                var1=var2
          }
     }
}
if(win_max_alrm==10){
    counter++;
 }
}
This is a long cycle but ther are just a few assigment and incrementation, and all the variables are integers.

Sorry for my style, but i am new in programing.

Re: slow processing

Posted: Thu Sep 27, 2018 1:11 pm
by ESP_Sprite
Can you actually post your actual code, instead of what I assume (hope) is pseudocode? Small things make a large difference when looking at compiler time optimizations.

Re: slow processing

Posted: Fri Sep 28, 2018 5:24 am
by Tebron
This is a multi-file project, i post the file with the problem.


This is in the main file where the task is called:

Code: Select all

xTaskCreatePinnedToCore(&img_prc,"img_prc",4096,NULL,5,NULL,1);

And this is the actual code

Code: Select all

static const char* TAG = "Image process: ";

typedef struct {
  vospi_frame_t frames[9];
 
} b_frame_t;

typedef struct {
  uint8_t ux;
  uint8_t uy;
  uint8_t dx;
  uint8_t dy;
  uint8_t eng;
} roi_t;
uint16_t diff_frame[60][80];
	uint16_t mask[60][80];
	
void img_prc(void){
	int counter=0;
	double time; 
	ESP_LOGI(TAG,"Heap size: %d",xPortGetFreeHeapSize());
	ESP_LOGI(TAG,"Heap block: %d",heap_caps_get_largest_free_block(MALLOC_CAP_DMA));
	b_frame_t* frame = heap_caps_malloc(((sizeof(b_frame_t))), MALLOC_CAP_DMA);
    static vospi_frame_t act_frame;
	
	ESP_LOGI(TAG,"Heap size: %d",xPortGetFreeHeapSize());
	ESP_LOGI(TAG,"Heap block: %d",heap_caps_get_largest_free_block(MALLOC_CAP_DMA));
	int i=0;
	int j=0;
	int prev_fn=-1;
	int newframe=0;
	int apix;
	int avg;
	
	uint8_t prev_distance=4;
	double cut=1.5;
	uint8_t winx=3;
	uint8_t winy=10;
	uint8_t limit=50;
	uint8_t scatter=4;
	
	roi_t roi[4];
	
	roi[0].ux=0;
	roi[0].uy=0;
	roi[0].dx=79;
	 roi[0].dy=59;
	 roi[0].eng=1;	
	 
	uint16_t pixn=0;
	
    uint8_t win_buf_lim[80];
    uint8_t win_buf_cor[80];
	
	int64_t scat;
	int square;
	
	for(int k=0;k<60;k++){
		for(int l=0;l<80;l++){
			for(int p=0;p<4;p++){
				if(roi[p].ux!=roi[p].dx){
					if(roi[p].eng==1){
						if(roi[p].ux<=l && roi[p].dx>=l && roi[p].uy<=k && roi[p].dy>=k && mask[k][l]!=0xffff){
							mask[k][l]|=0xffff;
							pixn++;

					}else{
						if(roi[p].ux<=l && roi[p].dx>=l && roi[p].uy<=k && roi[p].dy>=k && mask[k][l]==0xffff){
							mask[k][l]&=0x0000;
							pixn--;
						}

					}
				}	
			}
		}
	}
	
	ESP_LOGI(TAG,"pixn: %d",pixn);
	
	int win_buf_dif[80];

 
 int re=0;
	while(1){
		TIMERG0.wdt_wprotect=TIMG_WDT_WKEY_VALUE;
		TIMERG0.wdt_feed=1;
		TIMERG0.wdt_wprotect=0;
			
		if (xSemaphoreTake(c_frame.sem, 1000) == pdTRUE) {
			int fn=c_frame.frame.packets[60].symbols[42]<<24|c_frame.frame.packets[60].symbols[43]<<16|c_frame.frame.packets[60].symbols[40]<<8|c_frame.frame.packets[60].symbols[41];
		  if(prev_fn!=fn){
				memcpy(&act_frame, &c_frame.frame, sizeof(vospi_frame_t));
			  prev_fn=fn;
			  
			  newframe=1;
		  }
			xSemaphoreGive(c_frame.sem);
		}else {
			ESP_LOGW(TAG, "couldn't obtain c_frame sem, dropping frame");
		}
		
		if(newframe==1){

			time=act_time();

			avg=0;
			j=i;
			for(int p=0;p<9-prev_distance;p++){			
				j++;
				if(j>8)
					j=0;
			}
			
				for(int k=0;k<60;k++){
					for(int l=0;l<160;l+=2){
						apix=(act_frame.packets[k].symbols[l]<<8|act_frame.packets[k].symbols[l+1]) - (frame->frames[j].packets[k].symbols[l]<<8|frame->frames[j].packets[k].symbols[l+1]);
						diff_frame[k][l/2]=abs(apix)&mask[k][l/2];
						avg+=abs(apix);
					}
				}
				scat=0;
				avg/=pixn;

				for(int k=0;k<60;k++){
					for(int l=0;l<80;l++){
						square=((diff_frame[k][l])-avg);
						scat+=(square*square)&mask[k][l];
					}
				}
				scat=sqrtl(scat/(pixn-1));
			
			int win_lim_val=0;
			int win_dif_val=0;
			int win_cor_val=0;
			
			int win_max_alrm=0;
			int win_max_x=0;
			int win_max_y=0;
			int win_max_value=0;

			if((scat>scatter)){
				
				for(int k=59;k>=(winy-1);k--){

					win_lim_val=0;
					win_dif_val=0;
					win_cor_val=0;
					
					for(int l=0;l<winx;l++){
						win_buf_lim[l]=0;
						win_buf_cor[l]=0;
						win_buf_dif[l]=0;
						for(int p=0;p<winy;p++){
							
							if(diff_frame[k-p][l]>(avg*cut)){
								win_buf_lim[l]++;
								win_buf_dif[l]+=diff_frame[k-p][l];
								if(!mask[k-p][l]){
									win_buf_cor[l]=1;
									win_cor_val++;
								}
								win_lim_val++;
								win_dif_val+=diff_frame[k-p][l];
							}
						}
					}
					
					re =((win_lim_val*100)/(winx*winy));
					if( (win_cor_val==0) && (re>limit) ){
						win_max_alrm=1;
						if(win_max_value<(win_dif_val/win_lim_val)){
							win_max_value=win_dif_val/win_lim_val;
							win_max_y=k-winy/2;
							win_max_x=winx/2;
						}
					}
					
					for(int l=winx;l<80;l++){
						win_buf_lim[l]=0;
						win_buf_cor[l]=0;
						win_buf_dif[l]=0;
						
						for(int p=0;p<winy;p++){
							if(diff_frame[k-p][l]>(avg*cut)){
								win_buf_lim[l]++;
								win_buf_dif[l]+=diff_frame[k-p][l];
								if(!mask[k-p][l]){
									win_buf_cor[l]=1;
								}
							}
						}
						win_cor_val+=win_buf_cor[l]-win_buf_cor[l-winx];
						win_lim_val+=win_buf_lim[l]-win_buf_lim[l-winx];
						win_dif_val=win_buf_dif[l]-win_buf_dif[l-winx];

						re =((win_lim_val*100)/(winx*winy));//if i put this in the if condition below, it will cause the problem

						if( (win_cor_val==0) && (re>limit) ){
							win_max_alrm=1;
							if(win_max_value<(win_dif_val/win_lim_val)){
								win_max_value=win_dif_val/win_lim_val;
								
								win_max_y=k-winy/2;
								win_max_x=l-winx/2;
							}
						}
					}
				}
				if(win_max_alrm==1){
					ESP_LOGW("TAG","ALARM %d",win_max_value);  //if i comment this, the process will be faster	
				}
				
			}
			ESP_LOGI(TAG,"Time: %f",act_time()-time);	
			if (xSemaphoreTake(cpp_frame.sem, 100) == pdTRUE) {
			memcpy(&cpp_frame.frame, &act_frame, sizeof(vospi_frame_t));
			xSemaphoreGive(cpp_frame.sem);
			}
			memcpy(&(frame->frames[i]), &act_frame, sizeof(vospi_frame_t));
			
			i++;

			newframe=0;

		}
		if(i>8)
			i=0;
	}
}

Re: slow processing

Posted: Fri Sep 28, 2018 9:01 am
by ESP_Sprite
Do you actually do something with the variables you crunch in that big loop? Because if all you do is to check win_max_alrm==1 afterwards, if you comment out that code (or effectively make it effect-less, by leaving in the if but removing the ESP_LOGW), the compiler will most likely conclude that the entire loop has no effect and remove it.

Re: slow processing

Posted: Fri Sep 28, 2018 9:55 am
by Tebron
No, i dont use that, but that code will be written later. I just wanted test this part.
I did not know the compailer can remove code because that has no effect.

Thank You for the fast answers