|
|
|
@ -41,9 +41,10 @@ template<typename T> int amsarray_quicksort_round(
|
|
|
|
|
if(v2<v1)
|
|
|
|
|
{
|
|
|
|
|
//swap permutation indices
|
|
|
|
|
tmp = permarray->data[range.a];
|
|
|
|
|
permarray->data[range.a] = permarray->data[range.b-1];
|
|
|
|
|
permarray->data[range.b-1] = tmp;
|
|
|
|
|
amsarray_permutation_swap(permarray,range.a,range.b-1);
|
|
|
|
|
// tmp = permarray->data[range.a];
|
|
|
|
|
// permarray->data[range.a] = permarray->data[range.b-1];
|
|
|
|
|
// permarray->data[range.b-1] = tmp;
|
|
|
|
|
}
|
|
|
|
|
//there is no more work to be done within this range
|
|
|
|
|
*leftrange = ams::pair<amsarray_size_t,amsarray_size_t>(-1,-1);
|
|
|
|
@ -63,18 +64,28 @@ template<typename T> int amsarray_quicksort_round(
|
|
|
|
|
amsarray_permutation_swap(permarray,P,range.b-1);
|
|
|
|
|
P = range.b-1;
|
|
|
|
|
|
|
|
|
|
// amsarray_permutation_swap(permarray,P,range.a);
|
|
|
|
|
// P = range.a;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
J = range.a;
|
|
|
|
|
for(I=range.a;I<range.b-1;I++)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
//printf("debug: I=%ld, J=%ld, P=%ld, a=%1.3f, b=%1.3f\n",I,J,P,
|
|
|
|
|
// (double)array->data[permarray->data[I]],(double)array->data[permarray->data[P]]);
|
|
|
|
|
|
|
|
|
|
if(array->data[permarray->data[I]]<array->data[permarray->data[P]])
|
|
|
|
|
{
|
|
|
|
|
if(J!=I)
|
|
|
|
|
{
|
|
|
|
|
//printf("debug: swap\n");
|
|
|
|
|
amsarray_permutation_swap(permarray,I,J);
|
|
|
|
|
J++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//printf("debug: skip\n");
|
|
|
|
|
J++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -119,6 +130,42 @@ template<typename T> int amsarray_quicksort_round(
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T> int amsarray_quicksort_subrange(
|
|
|
|
|
amsarray<T> *array, //size N - array to sort
|
|
|
|
|
amsarray<amsarray_size_t> *permarray, //size N - permutation of sorting
|
|
|
|
|
ams::pair<amsarray_size_t,amsarray_size_t> _range
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
int ret = amsarray_success;
|
|
|
|
|
int res;
|
|
|
|
|
|
|
|
|
|
amsarray<ams::pair<amsarray_size_t,amsarray_size_t>> ranges;
|
|
|
|
|
amsarray_size_t rangeptr = 0;
|
|
|
|
|
ams::pair<amsarray_size_t,amsarray_size_t> range,rangeleft,rangeright;
|
|
|
|
|
|
|
|
|
|
ranges.append(_range);
|
|
|
|
|
rangeptr = 0;
|
|
|
|
|
while(rangeptr<ranges.length)
|
|
|
|
|
{
|
|
|
|
|
//printf("debug2:"); _debug_amsarray_print(permarray);
|
|
|
|
|
range = ranges[rangeptr];
|
|
|
|
|
rangeptr++;
|
|
|
|
|
//printf("debug3: range=(%d,%d)\n",(int)range.a,(int)range.b);
|
|
|
|
|
amsarray_quicksort_round(array,permarray,range,&rangeleft,&rangeright);
|
|
|
|
|
if(rangeleft.a>=0 && rangeleft.b>rangeleft.a)
|
|
|
|
|
{
|
|
|
|
|
ranges.append(rangeleft);
|
|
|
|
|
}
|
|
|
|
|
if(rangeright.a>=0 && rangeright.b>rangeright.a)
|
|
|
|
|
{
|
|
|
|
|
ranges.append(rangeright);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<typename T> int amsarray_quicksort_unthreaded(
|
|
|
|
|
amsarray<T> *array, //size N - array to sort
|
|
|
|
|
amsarray<amsarray_size_t> *permarray //size N - permutation of sorting
|
|
|
|
@ -145,8 +192,10 @@ template<typename T> int amsarray_quicksort_unthreaded(
|
|
|
|
|
rangeptr = 0;
|
|
|
|
|
while(rangeptr<ranges.length)
|
|
|
|
|
{
|
|
|
|
|
//printf("debug2:"); _debug_amsarray_print(permarray);
|
|
|
|
|
range = ranges[rangeptr];
|
|
|
|
|
rangeptr++;
|
|
|
|
|
//printf("debug3: range=(%d,%d)\n",(int)range.a,(int)range.b);
|
|
|
|
|
amsarray_quicksort_round(array,permarray,range,&rangeleft,&rangeright);
|
|
|
|
|
if(rangeleft.a>=0 && rangeleft.b>rangeleft.a)
|
|
|
|
|
{
|
|
|
|
@ -173,6 +222,18 @@ template<typename T> void amsarray_quicksort_tf(
|
|
|
|
|
|
|
|
|
|
ams::pair<amsarray_size_t,amsarray_size_t> rangeleft,rangeright;
|
|
|
|
|
|
|
|
|
|
if(range.b-range.a < amsarray_sortthreadpsize)
|
|
|
|
|
{
|
|
|
|
|
res = amsarray_quicksort_subrange(
|
|
|
|
|
array,
|
|
|
|
|
permarray,
|
|
|
|
|
range
|
|
|
|
|
);
|
|
|
|
|
//there should be no work to be done after this
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//range is too big, quicksort the pivot and supply subranges
|
|
|
|
|
res = amsarray_quicksort_round(
|
|
|
|
|
array,
|
|
|
|
|
permarray,
|
|
|
|
@ -194,10 +255,15 @@ template<typename T> void amsarray_quicksort_tf(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//end critical section (end of function)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//TODO - if the range falls below a specified size, I want to be able to run through
|
|
|
|
|
// quicksorting the entire range within a thread before returning
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template<typename T> int amsarray_quicksort_threaded(
|
|
|
|
|
amsarray<T> *array, //size N - array to sort
|
|
|
|
|
amsarray<amsarray_size_t> *permarray //size N - permutation of sorting
|
|
|
|
@ -240,9 +306,13 @@ template<typename T> int amsarray_quicksort_threaded(
|
|
|
|
|
nthreads = ranges.length-rangeptr;
|
|
|
|
|
nthreads = (nthreads>maxthreads) ? maxthreads : nthreads;
|
|
|
|
|
|
|
|
|
|
//printf("debug: %d %d %ld %ld\n",nthreads,maxthreads,rangeptr,ranges.length);
|
|
|
|
|
for(I=0;I<nthreads;I++)
|
|
|
|
|
{
|
|
|
|
|
range = ranges[rangeptr+I];
|
|
|
|
|
threadlock.lock();
|
|
|
|
|
range = ranges[rangeptr]; rangeptr++;
|
|
|
|
|
threadlock.unlock();
|
|
|
|
|
//printf("debug: thread %ld exec with range(%ld,%ld), rptr=%ld rlen=%ld\n",I,range.a,range.b,rangeptr,ranges.length);
|
|
|
|
|
threads[I] = new(std::nothrow) std::thread(
|
|
|
|
|
amsarray_quicksort_tf<T>,
|
|
|
|
|
array,permarray,
|
|
|
|
@ -259,6 +329,7 @@ template<typename T> int amsarray_quicksort_threaded(
|
|
|
|
|
ret = amsarray_failure;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//printf("debug3\n");
|
|
|
|
|
for(I=0;I<nthreads;I++)
|
|
|
|
|
{
|
|
|
|
|
if(threads[I]!=NULL)
|
|
|
|
@ -267,7 +338,7 @@ template<typename T> int amsarray_quicksort_threaded(
|
|
|
|
|
delete threads[I];
|
|
|
|
|
threads[I] = NULL;
|
|
|
|
|
}
|
|
|
|
|
rangeptr++;
|
|
|
|
|
//rangeptr++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -292,7 +363,7 @@ template<typename T> int amsarray_quicksort(
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(array->length<amsmathutil25_threadpsz)
|
|
|
|
|
if(array->length<amsarray_sortthreadpsize)
|
|
|
|
|
{
|
|
|
|
|
//perform unthreaded quicksort
|
|
|
|
|
ret = amsarray_quicksort_unthreaded(
|
|
|
|
|