MATLAB Answers

1

C++11 <thread> does not work properly in Matlab? It works.

I'm using 32-bit version of Matlab 2013a in Windows 7 64-bit OS.
I installed Microsoft Visual Studio 2012 Express that supports many C++11 features. Then I did "mex -setup". The default directory information for the installed Visual C++ was different (C:\Program Files\...) from the default install location of the compiler, so I corrected it (to C:\Program Files (x86)\...).
Then I wrote a very simple code, called mexfunction2.cpp. In this code, a newly generated thread updates a global variable, and the main original thread prints it. The code looks like this:
#include "mex.h"
#include <<thread>>
int count_thread1 = 0;
int count_thread2 = 0;
void hello()
{
for (long long int i=1;i<1000000000;i++)
{
count_thread2++; // update a global variable
}
}
// Matlab mexfunction
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
count_thread1 = 0;
count_thread2 = 0;
std::thread t(hello);
//t.join(); // to make the new thread finish before printing
for (int j=1;j<100;j++)
{
count_thread1 = 1;
for (long long int k=1;k<10000000;k++); // some delay between printf
mexPrintf(" %d %d:", count_thread1, count_thread2); // print the variable
//if (j==3)
// t.join(); // to see if something wrong... manual debugging
}
mexPrintf("\n");
t.join();
}
Then the output looks like this:
1 0: 1 0: 1 0: 1 0: 1 0: 1 0: 1 0: 1 0: 1 0: 1 0: 1 0: ......
This shouldn't be like this. I was expecting the zeros above to be some increasing numbers. I changed the position of t.join() to different parts of the codes and it was obvious that there was no new thread running background and threading was simulated. To check if I did something seriously wrong, I wrote an equivalent code in Visual Studio, which is exactly the same compiler (I assume because that is the only Visual C++ compiler in the machine):
#include "stdafx.h"
#include <<thread>>
#include <<iostream>>
int count_thread1 = 0;
int count_thread2 = 0;
void hello()
{
for (long long int i=1;i<1000000000;i++)
{
count_thread2++; // updates the global variable
}
}
// Microsoft Visual C++ console application main function
int _tmain(int argc, _TCHAR* argv[])
{
count_thread1 = 0;
count_thread2 = 0;
std::thread t(hello);
//t.join();
for (int j=1;j<100;j++)
{
count_thread1 = 1;
for (long long int k=1;k<10000000;k++); // some delay
std::cout<<" "<< count_thread1 << " " << count_thread2 << ":"; // print out
//if (j==3)
// t.join();
}
t.join();
return 0;
}
Then the output of this application shows:
1 12653651: 1 26374767: 1 39375259: 1 52980165: 1 65144711: 1 79238930: 1 93211 994: 1 107331017: 1 120377626: 1 133448865: 1 147428833: 1 161250113: 1 17522040: ...
which is what I expected from a multi-thread program.
So, my question is simple. Why do the codes using the same compiler show different result? Why does the mex file not spawn a new thread?
Thank you.

  0 Comments

Sign in to comment.

1 Answer

Answer by Sung Soo Kim on 12 Apr 2013
 Accepted Answer

The problem was because of compiler's optimization. The original codes shown above include some dummy for-loops for time-delay. That was simply taken out of the code by compiler for optimization, which resulted in a super quick execution of the new thread.
The new simplified codes shown below include some meaningful addition and subtraction within the for-loops.
And the result shows expected asynchronous execution of each thread.
// This code uses "printf", which I didn't confirm thread-safty in Matlab.
// This code does not utilize mutex or other concurrent programming tools.
// The only purpose of this code is to show that C++11 can be used in
// Matlab 2013a with Microsoft Visual Studio 2012 Express.
#include "mex.h"
#include <thread>
#include <stdio.h>
int count_thread1 = 0;
int count_thread2 = 0;
void hello()
{
count_thread2 = 0;
for(int i=0; i<=10000; i++){
for (int j=1;j<=20000;j++){
count_thread2 = i-j-1;
}
count_thread2++;
printf("2: %d , %d\n", count_thread1, count_thread2); // Not sure if printf is thread-safe in Matlab. But it works in this particular example
}
}
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
count_thread1 = 0;
std::thread t(hello);
for (int i=1;i<=10000;i++)
{
for (int j=1;j<=20000;j++){
count_thread1 = -i+j-1;
}
count_thread1++;
mexPrintf("1: %d , %d\n", count_thread1, count_thread2);
}
mexPrintf("\n");
t.join();
mexPrintf("Done\n");
}
The output looks like:
2: 10744 , -10033
1: 10743 , -10033
2: 10743 , -10032
2: 10742 , -10031
2: 10742 , -10030
1: 10742 , -10032
2: 10742 , -10029
2: 10741 , -10028
2: 10741 , -10027
2: 10741 , -10026
1: 10741 , -10029
2: 10741 , -10025
1: 10740 , -10025
.......................
2: 10718 , -10002
1: 10717 , -10002
2: 10717 , -10001
1: 10716 , -10001
2: 10716 , -10000
1: 10715 , -10000
1: 10714 , -10000
1: 10713 , -10000

  0 Comments

Sign in to comment.