Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7942 Discussions

multithreading problem - debud VS release mode

noiserv
Beginner
429 Views
Helllo guys,

My name is David and i'm having a really big problem...

I trying to program a multithread software...i use Visual Studio 2008 (Professional edition)...in a Windows XP Win64...

My problem is everything works perfect in Debud mode...the problem is in the release mode...

It compiles prefect...but then i doesn't work...:(

The program stays blocked when it open the first thread...e nothing heppens after...

Can anyone help me?

Thanks in advance,
David
0 Kudos
8 Replies
Michael_K_Intel2
Employee
429 Views
Quoting - noiserv
Helllo guys,

My name is David and i'm having a really big problem...

I trying to program a multithread software...i use Visual Studio 2008 (Professional edition)...in a Windows XP Win64...

My problem is everything works perfect in Debud mode...the problem is in the release mode...

It compiles prefect...but then i doesn't work...:(

The program stays blocked when it open the first thread...e nothing heppens after...

Can anyone help me?

Thanks in advance,
David

Hi David,

your problem could be related to anything, as it is hard tell what could be wrong from your description. Can you help us by providing more information on the compiler and the compiler options you use? It would also be great if you could post a minimal program that still shows the problem. Otherwise, it is virtually impossible to track down the problem and find a solution for it.

Cheers,
-michael

0 Kudos
noiserv
Beginner
429 Views

Hi David,

your problem could be related to anything, as it is hard tell what could be wrong from your description. Can you help us by providing more information on the compiler and the compiler options you use? It would also be great if you could post a minimal program that still shows the problem. Otherwise, it is virtually impossible to track down the problem and find a solution for it.

Cheers,
-michael


Thanks a lot for your quick reply...

but the strange thing is that it compile correctly...i will try to here some code:

unsigned __stdcall ThreadFunc_change_position( void* pArguments )
{

printf( "In first thread...n" );

while(1){

//Sleep(10);

//////#posio inicial
//////receiver->x = -2.0;
//////receiver->y = 3.0;
//////receiver->z = 1.2;
//while (receiver->y<8){
//receiver->y = receiver->y; //translao

//new_sources_images=1;
//}
}
_endthreadex( 0 );
return 0;
}


unsigned __stdcall ThreadFunc_source_images( void* pArguments )
{

printf( "In second thread...n" );

while(1){
while(new_sources_images==0){}

cout << "1"<< endl;
cout << "first_time_images=" << first_time_images << endl;
source_images_estimation ();
first_time_images=1;
cout << "first_time_images=" << first_time_images << endl;
new_binaural=1;//varivel para o programa calcular uma nova binaural
new_sources_images=0;
}
_endthreadex( 0 );
return 0;
}

unsigned __stdcall ThreadFunc_binaural( void* pArguments )
{

printf( "In third thread...n" );

while(1){
while(new_binaural==0){}
receiver_source_distance_azimuth_elevation();
//calculatestaticalimages();
//Calculo do sinal binaural de acordo com as fontes clculadas
Binaural_L_R_estimation ();
//"""""""""
first_time_Binaural=1;
new_binaural=0;
}
_endthreadex( 0 );
return 0;
}

unsigned __stdcall ThreadFunc_convolution_left_right( void* pArguments )
{

printf( "In fourth thread...n" );
convolution_left_right();
_endthreadex( 0 );
return 0;
}



int main(){
uint i, j, k = 0, x,y, s;
int value;





HANDLE hThread_change_position;
unsigned threadID_change_position;
// Create the second thread.
hThread_change_position = (HANDLE)_beginthreadex( NULL, 0, &ThreadFunc_change_position, NULL, 0, &threadID_change_position );



readWave(soundfilename);
//"""""""""
Sound_lenght=graph_nr_points;
//"""""""""


HANDLE hThread_source_images;
unsigned threadID_source_images;
// Create the 2 thread.
hThread_source_images = (HANDLE)_beginthreadex( NULL, 0, &ThreadFunc_source_images, NULL, 0, &threadID_source_images );


while (first_time_images==0){
}



HANDLE hThread_binaural;
unsigned threadID_binaural;
// Create the 3 thread.
hThread_binaural = (HANDLE)_beginthreadex( NULL, 0, &ThreadFunc_binaural, NULL, 0, &threadID_binaural );
while (first_time_Binaural==0){
}


//##construco da thread para o convoluo para o ouvido esquerdo e direito
HANDLE hThread_convolution_left_right;
unsigned threadID_convolution_left_right;
// Create the 4 thread.
hThread_convolution_left_right = (HANDLE)_beginthreadex( NULL, 0, &ThreadFunc_convolution_left_right, NULL, 0, &threadID_convolution_left_right );

while (streaming_start==0){
}

//##STREAMING
wave_stream2();


}

--------------------

Just like this it doens't work...but it's just for you to see the way that i use the threadss...


please help me....
0 Kudos
Michael_K_Intel2
Employee
429 Views
Quoting - noiserv

Thanks a lot for your quick reply...

but the strange thing is that it compile correctly...i will try to here some code:

[...]

Just like this it doens't work...but it's just for you to see the way that i use the threadss...


please help me....

This is a loop from the above code:

while(new_sources_images==0){}

I assume that the loop should keep the corresponding thread spinning until new_sources_images is set to something non-zero. If that is the case, the problem is the following:

Your C compiler does not have any notion of multi-threading. Hence, it sees that the same variable is read over and over again and puts the variable into some register without reloading it while your loop executes. If another thread changes the variable, the new value does not get propagated into the register to break out of the spinning loop. Your code works in Debug mode, as normally optimizations (and therefore register allocation) are turned off when debug-enabled code is emitted.

Can you please change all those variables that you use to implement a so-called spin-lock to "volatile", e.g. volatile int new_sources_image?

Let me know if my assumption is wrong or if I was right and the "volatile" modifier solved your problem.

Cheers,
-michael





0 Kudos
noiserv
Beginner
429 Views

This is a loop from the above code:

while(new_sources_images==0){}

I assume that the loop should keep the corresponding thread spinning until new_sources_images is set to something non-zero. If that is the case, the problem is the following:

Your C compiler does not have any notion of multi-threading. Hence, it sees that the same variable is read over and over again and puts the variable into some register without reloading it while your loop executes. If another thread changes the variable, the new value does not get propagated into the register to break out of the spinning loop. Your code works in Debug mode, as normally optimizations (and therefore register allocation) are turned off when debug-enabled code is emitted.

Can you please change all those variables that you use to implement a so-called spin-lock to "volatile", e.g. volatile int new_sources_image?

Let me know if my assumption is wrong or if I was right and the "volatile" modifier solved your problem.

Cheers,
-michael






wow....

thanks a lot man...it works...
But i want to ask you something different...in my code:

-----
unsigned __stdcall ThreadFunc_source_images( void* pArguments )
{
while(1){
while(new_sources_images==0){}
source_images_estimation ();
new_sources_images=0;
}
_endthreadex( 0 );
return 0;
}
-----

The idea is:
while (1) -> is to the thread be always opened
however i only need to run "source_images_estimation ();", when somethign changes in the main code, and so in that cases i change variable "new_sources_images=0;" to 1

So i had put this "while(new_sources_images==0){}" to the thread don't run "source_images_estimation ();", the problem is that the thread still working the comparition...

Is there anyway to pause the thread and just start it again when something change in the main code?

thanks thanks a lot for your help...it's being amazing...
0 Kudos
Michael_K_Intel2
Employee
429 Views
Quoting - noiserv

wow....

thanks a lot man...it works...
But i want to ask you something different...in my code:

-----
unsigned __stdcall ThreadFunc_source_images( void* pArguments )
{
while(1){
while(new_sources_images==0){}
source_images_estimation ();
new_sources_images=0;
}
_endthreadex( 0 );
return 0;
}
-----

The idea is:
while (1) -> is to the thread be always opened
however i only need to run "source_images_estimation ();", when somethign changes in the main code, and so in that cases i change variable "new_sources_images=0;" to 1

So i had put this "while(new_sources_images==0){}" to the thread don't run "source_images_estimation ();", the problem is that the thread still working the comparition...

Is there anyway to pause the thread and just start it again when something change in the main code?

thanks thanks a lot for your help...it's being amazing...

Hi David,

there are always several options that you can use :-).

Let's start with the while(1) loop to keep threads alive. It's often better to have a while(not_terminated) loop instead. That gives you a change to call a method and set that flag to indicate that a thread should terminate cooperatively, that is, when it has a change to do so.

To wait for threads, you've chosen to use spin-locks (BTW, it would be better to use a library implementation of these). With that, threads burn cycles while they wait for a flag to change. You could also put the thread into blocking wait. In that case, the thread goes to sleep and does not consume time on the CPU. However, it's more expensive to wake up the thread.

The right option depends on the application. Burning cycles puts extra loads on the system, but it cheaper to resume a thread. Blocking saves resources, but is more expensive in terms of wake-up time.

As I'm not a Windows threading guru, I can't give you the right API calls for spin-locks and blocking waits. Anyways, you can have a look at TBB that should offer API calls that you might want to exploit.

Cheers,
-michael

0 Kudos
jimdempseyatthecove
Honored Contributor III
429 Views

In addition to Michaels suggeston of using volatile, use _mm_pause() or some other form of wait in your wait loops

while (first_time_images==0){
_mm_pause();
}

Jim Dempsey


0 Kudos
matthieu_darbois
New Contributor III
429 Views
Hi,
Have a look at the msdn documentation : "Synchronization Functions". Here you'll find what the win32 API provides in terms of synchronization. You could for example use a semaphore to wait for new work.
Every OS has its own implementation of synchronization functions. If you want it to be easily portable across different platforms you could also work with glib for example.

Regards,
Matthieu

0 Kudos
joelkatz
Novice
429 Views

Please don't take offense at this, but you have more bugs than code. Please spend some time learning about multithreading and looking at working multithreaded programs before you try your hand at it.

while(new_sources_images==0){}
source_images_estimation ();
new_sources_images=0;
}

Just pointing out the one thing that jumped out at me -- you have no synchronization here. So if the other thread sets new_sources_images to one just before this thread sets it to zero, the code while spin in the 'while' loop even though there are new images.

Consider:

1) Thread A adds new images, tells thread B by setting new_sources_images.
2) Thread B calls sources_images_estimation, it returns.
3) Thread A adds more new images, sets new_sources_images.
4) Thread B sets news_sources_images to zero, because that happens after calling sources_images_estimation.
5) Thread B enters the while (new_sources_images==0) loop, waiting for the new images that happened in step 3.

You need to use proper synchronization tools to ensure your code doesn't have more race conditions than lines of code.
0 Kudos
Reply