Jump to content

  • Log In with Google      Sign In   
  • Create Account


very strange bug (when runing c basic arrays code)

  • This topic is locked This topic is locked
40 replies to this topic

#1 fir   Members   -  Reputation: -444

Like
0Likes
Like

Posted 30 June 2014 - 05:55 AM

I was testing such very simple code 

float modelRight_x = 1.1;
float modelRight_y = 1.2;
float modelRight_z = 1.3;
 
float modelUp_x = 1.1;
float modelUp_y = 1.2;
float modelUp_z = 1.3;
 
float modelDir_x = 1.1;
float modelDir_y = 1.2;
float modelDir_z = 1.3;
 
 
 float normal_x[100*1000];
 float normal_y[100*1000];
 float normal_z[100*1000];
 
 float n_x[100*1000];
 float n_y[100*1000];
 float n_z[100*1000];
 
 
 
void matrix_mul_float()
{
  for(int i=0; i<100*1000; i++)
  {
 
    normal_x[i] = n_x[i]*modelRight_x + n_y[i]*modelRight_y + n_z[i]*modelRight_z;
    normal_y[i] = n_x[i]*modelUp_x    + n_y[i]*modelUp_y    + n_z[i]*modelUp_z;
 //third line ->
    normal_z[i] = n_x[i]*modelDir_x   + n_y[i]*modelDir_y   + n_z[i]*modelDir_z;
 
   }
 
  return;
 
}

(dam those forum bug eated text again)

 

I got runtime crash on the third line , when comment this line its ok, when xchange it with normal_x[i] = ... line it crashes on those x third line then, it also works when changing 

 

    normal_z[i/2] = n_x[i]*modelDir_x   + n_y[i]*modelDir_y   + n_z[i]*modelDir_z;

 
very strange imo
 

    normal_z[i/1*1] = n_x[i]*modelDir_x   + n_y[i]*modelDir_y   + n_z[i]*modelDir_z;

 

crashes

 

    normal_z[i/2*2] = n_x[i]*modelDir_x   + n_y[i]*modelDir_y   + n_z[i]*modelDir_z;

 
not crashes
 
compile options
 

c:\mingw\bin\g++ -O3 -Ofast -w -c tests.c  -funsafe-math-optimizations -mrecip -ffast-math -fno-rtti -fno-exceptions -march=pentium4 -mtune=generic -mfpmath=both 
 

gcc 4.7.1

 

is this compiler bug?


Edited by fir, 30 June 2014 - 06:05 AM.


Sponsor:

#2 Bacterius   Crossbones+   -  Reputation: 8162

Like
4Likes
Like

Posted 30 June 2014 - 06:15 AM

Check that your loop limit isn't overflowing (the int type is only technically guaranteed to hold values from -32768 to +32767, and you did say you were using 32-bit XP in a previous thread). Set compiler warnings to maximum. Print the loop counter every iteration. Run through the code with a debugger and see which iteration fails. Is the bug consistent, does it always crash at the same place? If it sometimes succeeds, does it print the right answer or just garbage? What happens if you decrease the number of iterations? You know, the usual stuff. There's nothing wrong that I can spot with the code except the potential for overflow, and, indeed, it works just fine for me.

 

By the way, there is a difference between "doesn't crash" and "prints the right answer" - differentiating the two in your diagnostics usually helps. And also, please try to avoid tagging your thread "C language" when you are really compiling with a C++ compiler. The two languages are different and go by (often subtly) different rules - you will get into trouble eventually thinking they are interchangeable. Make up your mind on a language, be it C, C++, or C with classes, but please don't say you are using one language and then compile your code as another, that's just misleading for everyone involved.


The slowsort algorithm is a perfect illustration of the multiply and surrender paradigm, which is perhaps the single most important paradigm in the development of reluctant algorithms. The basic multiply and surrender strategy consists in replacing the problem at hand by two or more subproblems, each slightly simpler than the original, and continue multiplying subproblems and subsubproblems recursively in this fashion as long as possible. At some point the subproblems will all become so simple that their solution can no longer be postponed, and we will have to surrender. Experience shows that, in most cases, by the time this point is reached the total work will be substantially higher than what could have been wasted by a more direct approach.

 

- Pessimal Algorithms and Simplexity Analysis


#3 slicer4ever   Crossbones+   -  Reputation: 3205

Like
0Likes
Like

Posted 30 June 2014 - 06:17 AM

integer math:

 

5/1*1 = 5;

5/2*2 = 4; 5/2 = 2.5, the decimal is dropped with an integer, so you get 2*2 = 4.

 

re-check your allocation sizes, as the code you've posted shoudn't be crashing with those allocations.


Edited by slicer4ever, 30 June 2014 - 06:18 AM.

Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

#4 fir   Members   -  Reputation: -444

Like
-1Likes
Like

Posted 30 June 2014 - 06:24 AM

Think it is compiler bug - also vanishes (not crashes) when turning  "-O3 -Ofast " into "-O2"



#5 slicer4ever   Crossbones+   -  Reputation: 3205

Like
0Likes
Like

Posted 30 June 2014 - 06:31 AM

the fact that changing compiler settings "fixes" this bug likely indicates you've corrupted memory somewhere, and this is just where it's actually crashing.


Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

#6 fir   Members   -  Reputation: -444

Like
0Likes
Like

Posted 30 June 2014 - 06:45 AM

 

the fact that changing compiler settings "fixes" this bug likely indicates you've corrupted memory somewhere, and this is just where it's actually crashing.

 

byt this is just multiplication and addition code should work regardless of ram contents - what could be spoiled ? 

 

i got also crashes on such sse intrinsics code

 

 
void matrix_mul_sse()
{
 
   __m128 mRx = _mm_load_ps((const float*) &modelRight_4x);
   __m128 mRy = _mm_load_ps((const float*) &modelRight_4y);
   __m128 mRz = _mm_load_ps((const float*) &modelRight_4z);
                                          
   __m128 mUx = _mm_load_ps((const float*) &modelUp_4x);
   __m128 mUy = _mm_load_ps((const float*) &modelUp_4y);
   __m128 mUz = _mm_load_ps((const float*) &modelUp_4z);
                                          
   __m128 mDx = _mm_load_ps((const float*) &modelDir_4x);
   __m128 mDy = _mm_load_ps((const float*) &modelDir_4y);
   __m128 mDz = _mm_load_ps((const float*) &modelDir_4z);
 
  for(int i=0; i<100*1000; i+=4)
  {
 
   __m128 nx = _mm_load_ps( &n_x[i]);
   __m128 ny = _mm_load_ps( &n_y[i]);
   __m128 nz = _mm_load_ps( &n_z[i]);
 
   __m128 normalx = _mm_add_ps(_mm_add_ps(_mm_mul_ps(nx,mRx), _mm_mul_ps(ny,mRy)), _mm_mul_ps(nz,mRz));
   __m128 normaly = _mm_add_ps(_mm_add_ps(_mm_mul_ps(nx,mUx), _mm_mul_ps(ny,mUy)), _mm_mul_ps(nz,mUz));
   __m128 normalz = _mm_add_ps(_mm_add_ps(_mm_mul_ps(nx,mDx), _mm_mul_ps(ny,mDy)), _mm_mul_ps(nz,mDz));
 
    _mm_store_ps(  &normal_x[i], normalx);
//    _mm_store_ps(  &normal_y[i], normaly);
//    _mm_store_ps(  &normal_z[i], normalz);
 
 }
 
}

 
this not crashes but crashes when uncomment one of the commented lines
(as to this code i cannot be sure if this is ok as im very new to sse but also a bit strange) - [this crashes even when i got only -O2, not tested other cases]

Edited by fir, 30 June 2014 - 06:49 AM.


#7 Zaoshi Kaba   Crossbones+   -  Reputation: 3629

Like
2Likes
Like

Posted 30 June 2014 - 06:51 AM

100*1000 is 100,000 elements, 6 such arrays make 600,000 elements 4 bytes each, that's 2,400,000 bytes or over 2 MB. That's bigger than default stack size, that's why you get crash. Use new[] operator for those arrays and it'll work just fine.



#8 Brother Bob   Moderators   -  Reputation: 7781

Like
0Likes
Like

Posted 30 June 2014 - 07:01 AM

100*1000 is 100,000 elements, 6 such arrays make 600,000 elements 4 bytes each, that's 2,400,000 bytes or over 2 MB. That's bigger than default stack size, that's why you get crash. Use new[] operator for those arrays and it'll work just fine.

 

Assuming he didn't butcher the code completely when copying it, the arrays are defined at file scope and are not stack allocated. May still be a good idea to allocate them dynamically rather than statically though.



#9 Álvaro   Crossbones+   -  Reputation: 11886

Like
0Likes
Like

Posted 30 June 2014 - 07:14 AM

100*1000 is 100,000 elements, 6 such arrays make 600,000 elements 4 bytes each, that's 2,400,000 bytes or over 2 MB. That's bigger than default stack size, that's why you get crash. Use new[] operator for those arrays and it'll work just fine.


It looks like those arrays are global variables, and in that case this should be fine.

I suggest trying to simplify the program (ideally until it's just that function and a main() that does enough to call it), removing everything you can until you have a program that wouldn't show the problem if you removed anything from it. If that's the case, post the complete minimal program so we can try to reproduce the problem ourselves. But there is a good chance you'll find the problem yourself in the process of making the minimal program.

#10 Tribad   Members   -  Reputation: 802

Like
0Likes
Like

Posted 30 June 2014 - 08:01 AM

Allways compile -Wall and make sure you get no warnings. Warnings may differe with optimization levels.

#11 Tribad   Members   -  Reputation: 802

Like
0Likes
Like

Posted 30 June 2014 - 08:06 AM

Can make the source available? Think its some tricky trick that lead to the behaviour.

#12 fir   Members   -  Reputation: -444

Like
0Likes
Like

Posted 30 June 2014 - 09:17 AM

Can make the source available? Think its some tricky trick that lead to the behaviour.

 

the code is like i said

 

this is stripped to the bare win main version with the same settings to compilation

 

https://www.dropbox.com/s/ib4igh5qs85a156/test.zip

 

it do not crashes as it seem 

 

when I call it from within my program 

#include "fist.h"
#include <x86intrin.h>
 
 
float modelRight_x = 1.1;
float modelRight_y = 1.2;
float modelRight_z = 1.3;
 
float modelUp_x = 1.1;
float modelUp_y = 1.2;
float modelUp_z = 1.3;
 
float modelDir_x = 1.1;
float modelDir_y = 1.2;
float modelDir_z = 1.3;
 
 
 
__attribute__ ((aligned (16))) float normal_x[100*1000];
__attribute__ ((aligned (16))) float normal_y[100*1000];
__attribute__ ((aligned (16))) float normal_z[100*1000];
 
__attribute__ ((aligned (16))) float n_x[100*1000];
__attribute__ ((aligned (16))) float n_y[100*1000];
__attribute__ ((aligned (16))) float n_z[100*1000];
 
 
 
void initialize_data_for_matrix_mul()
{
 
 static int initialized = 0;
 if(initialized) return;
 initialized = 1;
 
 for(int i=0; i<100*1000; i++)
 {
  n_x[i] = (100.+rand()%10000)/1000.;
  n_y[i] = (100.+rand()%10000)/1000.;
  n_z[i] = (100.+rand()%10000)/1000.;
 }
 
}
 
void matrix_mul_float()
{
  for(int i=0; i<100*1000; i++)
  {
 
    normal_x[i] = n_x[i]*modelRight_x + n_y[i]*modelRight_y + n_z[i]*modelRight_z;
    normal_y[i] = n_x[i]*modelUp_x    + n_y[i]*modelUp_y    + n_z[i]*modelUp_z;
    normal_z[i] = n_x[i]*modelDir_x   + n_y[i]*modelDir_y   + n_z[i]*modelDir_z;
 
 
  }
  return;
 
}
 
//struct float4 { float x,y,z,w; };
 
 __attribute__ ((aligned (16))) float4 modelRight_4x = {1.1, 1.1, 1.1, 1.1 };
 __attribute__ ((aligned (16))) float4 modelRight_4y = {1.2, 1.2, 1.2, 1.2 };
 __attribute__ ((aligned (16))) float4 modelRight_4z = {1.3, 1.3, 1.3, 1.3 };
 
 __attribute__ ((aligned (16))) float4 modelUp_4x = {1.1, 1.1, 1.1, 1.1 };;
 __attribute__ ((aligned (16))) float4 modelUp_4y = {1.2, 1.2, 1.2, 1.2 };;
 __attribute__ ((aligned (16))) float4 modelUp_4z = {1.3, 1.3, 1.3, 1.3 };;
 
 __attribute__ ((aligned (16))) float4 modelDir_4x = {1.1, 1.1, 1.1, 1.1 };;
 __attribute__ ((aligned (16))) float4 modelDir_4y = {1.2, 1.2, 1.2, 1.2 };;
 __attribute__ ((aligned (16))) float4 modelDir_4z = {1.3, 1.3, 1.3, 1.3 };;
 
void matrix_mul_sse()
{
 
   __m128 mRx = _mm_load_ps((const float*) &modelRight_4x);
   __m128 mRy = _mm_load_ps((const float*) &modelRight_4y);
   __m128 mRz = _mm_load_ps((const float*) &modelRight_4z);
 
   __m128 mUx = _mm_load_ps((const float*) &modelUp_4x);
   __m128 mUy = _mm_load_ps((const float*) &modelUp_4y);
   __m128 mUz = _mm_load_ps((const float*) &modelUp_4z);
 
   __m128 mDx = _mm_load_ps((const float*) &modelDir_4x);
   __m128 mDy = _mm_load_ps((const float*) &modelDir_4y);
   __m128 mDz = _mm_load_ps((const float*) &modelDir_4z);
 
  for(int i=0; i<100*1000; i+=4)
  {
 
   __m128 nx = _mm_load_ps( &n_x[i]);
   __m128 ny = _mm_load_ps( &n_y[i]);
   __m128 nz = _mm_load_ps( &n_z[i]);
 
   __m128 normalx = _mm_add_ps(_mm_add_ps(_mm_mul_ps(nx,mRx), _mm_mul_ps(ny,mRy)), _mm_mul_ps(nz,mRz));
   __m128 normaly = _mm_add_ps(_mm_add_ps(_mm_mul_ps(nx,mUx), _mm_mul_ps(ny,mUy)), _mm_mul_ps(nz,mUz));
   __m128 normalz = _mm_add_ps(_mm_add_ps(_mm_mul_ps(nx,mDx), _mm_mul_ps(ny,mDy)), _mm_mul_ps(nz,mDz));
 
    _mm_store_ps(  &normal_x[i], normalx);
    _mm_store_ps(  &normal_y[i], normaly);
//    _mm_store_ps(  &normal_z[i], normalz);
 
 }
 
}
 
void tests()
{
 
   alert("\nstart");
 
   initialize_data_for_matrix_mul();
 
   alert("\nmul float");
 
    matrix_mul_float();
 
   alert("\nmul sse");
 
    matrix_mul_sse();
 
    alert("\ndone");
 
   exit(0);
 
}
 

with only chnge changing winmain to tests and including header of my framework, should bo nothing scary there (i could comment this), - this is linked as an seperate .o and called - it crashes as i said

 

commented header thus calling the same code as this separate win main that not crashes - only change is the renaming winmain to tests and calling this from my appilication (commandline scripts are the same except im linking more objects in my application) - this just crashes when called from my application (I call it in the main loop, could see what would be there if i call it from app setup)


Edited by fir, 30 June 2014 - 09:25 AM.


#13 phantom   Moderators   -  Reputation: 6791

Like
4Likes
Like

Posted 30 June 2014 - 10:21 AM

When it crashes what is the call stack?
What values to variables hold?
What is the content of the destination memory?
Is it what you expect?
What does the debugger tell you?

#14 fir   Members   -  Reputation: -444

Like
-1Likes
Like

Posted 30 June 2014 - 10:39 AM

When it crashes what is the call stack?
What values to variables hold?
What is the content of the destination memory?
Is it what you expect?
What does the debugger tell you?

 

callstack is obvious i think

 

ps, im talking now about this second crash (not the first possibly more mysterious one, (that with simple float code) - as i just off -O3 -Ofast and skipped this)

 

here it seem crash on the first sse line

 

 

  alert_("yo1");
        // CRaSH HERE
   __m128 mRx = _mm_load_ps((const float*) &modelRight_4x);
 
  alert_("yo2");
walues are 16-aligned I checked them in runtime


#15 Vortez   Crossbones+   -  Reputation: 2688

Like
0Likes
Like

Posted 30 June 2014 - 11:17 AM


100*1000 is 100,000 elements, 6 such arrays make 600,000 elements 4 bytes each, that's 2,400,000 bytes or over 2 MB. That's bigger than default stack size, that's why you get crash. Use new[] operator for those arrays and it'll work just fine.

 

You have your answer right there, stop blaming the compiler for your mistake. Either allocate the array with new(recommended) or increase the stack size. Default stack size is 1 Mb IIRC.


Edited by Vortez, 30 June 2014 - 11:20 AM.


#16 fir   Members   -  Reputation: -444

Like
-1Likes
Like

Posted 30 June 2014 - 11:19 AM

 


100*1000 is 100,000 elements, 6 such arrays make 600,000 elements 4 bytes each, that's 2,400,000 bytes or over 2 MB. That's bigger than default stack size, that's why you get crash. Use new[] operator for those arrays and it'll work just fine.

 

You have your answer right there, stop blaming the compiler for your mistake.

 

 

?



#17 Vortez   Crossbones+   -  Reputation: 2688

Like
0Likes
Like

Posted 30 June 2014 - 11:22 AM

You know how the stack work, right?

 

http://stackoverflow.com/questions/6219878/stack-overflow-c


Edited by Vortez, 30 June 2014 - 11:24 AM.


#18 fir   Members   -  Reputation: -444

Like
0Likes
Like

Posted 30 June 2014 - 11:30 AM

You know how the stack work, right?

 

http://stackoverflow.com/questions/6219878/stack-overflow-c

 

but it is not stack, or am i blind?

(checked and my stack values are 0x0020 0000 and static data 0x0040 0000 - this is static data - and is aligned



#19 Madhed   Crossbones+   -  Reputation: 2493

Like
0Likes
Like

Posted 30 June 2014 - 11:41 AM

So, did you run a debugger yet?



#20 fir   Members   -  Reputation: -444

Like
0Likes
Like

Posted 30 June 2014 - 12:02 PM

So, did you run a debugger yet?

what values you want to know - i will tel you

 

still got no idea what is the reason -

maybe this is some kind of sse mode i need to turn on or something?

 

i may say - i checked the _mm_loadu_ps and it crashes the same

also decrased the arrays size but it crashes the same







PARTNERS