#include <maya/MSimple.h>
#include <maya/MGlobal.h>
#include <maya/MIOStream.h>
#include <maya/MTimer.h>
#include <maya/MSpinLock.h>
#include <maya/MThreadUtils.h>
#include <tbb/blocked_range.h>
#include <tbb/parallel_for.h>
#include <tbb/parallel_reduce.h>
#include <mutex>
#include <atomic>
int doMutexCalc(int iterations, int val)
{
int sum = 0;
std::mutex mutex;
tbb::parallel_for(tbb::blocked_range<int>(0, iterations),
[&](const tbb::blocked_range<int> &br) {
for (int i = br.begin(); i < br.end(); i++) {
mutex.lock();
sum += val;
mutex.unlock();
}
});
return sum;
}
int doSpinCalc(int iterations, int val)
{
int sum = 0;
tbb::parallel_for(tbb::blocked_range<int>(0, iterations),
[&](const tbb::blocked_range<int> &br) {
for (int i = br.begin(); i < br.end(); i++) {
sum += val;
}
});
return sum;
}
int doAtomicCalc(int iterations, int val)
{
std::atomic<int> sum{ 0 };
tbb::parallel_for(tbb::blocked_range<int>(0, iterations),
[&](const tbb::blocked_range<int> &br) {
for (int i = br.begin(); i < br.end(); i++) {
sum += val;
}
});
return sum;
}
int doReductionCalc(int iterations, int val)
{
int sum = 0;
sum =
tbb::parallel_reduce(
tbb::blocked_range<unsigned int>(0, iterations, 8196),
0.0,
[=](const tbb::blocked_range<unsigned int> &br, int init)->int {
for (unsigned int i = br.begin(); i != br.end(); i++) {
init += val;
}
return init;
},
[](int x, int y)->int { return x + y; }
);
return sum;
}
int doUnsafeCalc(int iterations, int val)
{
int sum = 0;
tbb::parallel_for(tbb::blocked_range<int>(0, iterations),
[&](const tbb::blocked_range<int> &br) {
for (int i = br.begin(); i < br.end(); i++) {
sum += val;
}
});
return sum;
}
int doSerialCalc(int iterations, int val)
{
int sum = 0;
for(int i=0; i<iterations; i++) {
sum += val;
}
return sum;
}
{
if ( MS::kSuccess != stat )
cout<<"Error creating curve."<<endl;
MString str =
MString(
"Invalid number of arguments, usage: threadingLockTests 1000000");
}
int iterations = args.
asInt( 0, &stat );
int increment = 2;
int sum = 0;
int repeat = 1;
for(int i=0; i<repeat; i++) {
sum = doMutexCalc(iterations, increment);
if(sum != iterations*increment) {
printf("doMutexCalc failed, sum %d\n", sum);
break;
}
}
for(int i=0; i<repeat; i++) {
sum = doSpinCalc(iterations, increment);
if(sum != iterations*increment) {
printf("doSpinCalc failed, sum %d\n", sum);
break;
}
}
for(int i=0; i<repeat; i++) {
sum = doAtomicCalc(iterations, increment);
if(sum != iterations*increment) {
printf("doAtomicCalc failed, sum %d\n", sum);
break;
}
}
for(int i=0; i<repeat; i++) {
sum = doReductionCalc(iterations, increment);
if(sum != iterations*increment) {
printf("doReductionCalc failed, sum %d\n", sum);
break;
}
}
for(int i=0; i<repeat; i++) {
sum = doUnsafeCalc(iterations, increment);
if(sum != iterations*increment) {
printf("doUnsafeCalc failed, sum %d\n", sum);
break;
}
}
for(int i=0; i<repeat; i++) {
sum = doSerialCalc(iterations, increment);
if(sum != iterations*increment) {
printf("doUnthreadedCalc failed, sum %d\n", sum);
break;
}
}
return stat;
}