void sort_parallel(int a[], int first, int last, int threads) { if (threads <= 1 || (last - first) <= 100) { sort_serial(a, first, last); } else { int middle = first + (last - first) / 2; #pragma omp parallel sections { #pragma omp section sort_parallel(a, first, middle, threads / 2 + 1); #pragma omp section sort_parallel(a, middle, last, threads / 2 + 1); } merge(a, first, middle, last); } }
int main(int argc, char **argv) { FILE *f = fopen(INPUT_FILE, "r"); if (f == NULL) { printf("Failed to open input file: %s\n", strerror(errno)); goto exit; } int size = 0; while (!feof(f)) { if (size > MAX_SIZE) { printf("Too much numbers\n"); break; } if (fscanf(f, "%d", &(array[size])) <= 0) { break; } size++; } printf("Read %d numbers\n", size); int num_of_threads = 8; //omp_get_num_threads(); omp_set_num_threads(num_of_threads); printf("Sorting numbers with %d threads\n", num_of_threads); sort_parallel(array, 0, size, num_of_threads); sort_serial(array, 0, size); save_result(array, size); fclose(f); exit: return 0; }
void FMEMultipoleKernel::quadtreeConstruction(ArrayPartition& pointPartition) { FMELocalContext* localContext = m_pLocalContext; FMEGlobalContext* globalContext = m_pGlobalContext; LinearQuadtree& tree = *globalContext->pQuadtree; // precompute the bounding box for the quadtree points from the graph nodes for_loop(pointPartition, min_max_x_function(localContext)); for_loop(pointPartition, min_max_y_function(localContext)); // wait until the thread's bounding box is computed sync(); // let the main thread computed the bounding box of the bounding boxes if (isMainThread()) { globalContext->min_x = globalContext->pLocalContext[0]->min_x; globalContext->min_y = globalContext->pLocalContext[0]->min_y; globalContext->max_x = globalContext->pLocalContext[0]->max_x; globalContext->max_y = globalContext->pLocalContext[0]->max_y; for (__uint32 j=1; j < numThreads(); j++) { globalContext->min_x = min(globalContext->min_x, globalContext->pLocalContext[j]->min_x); globalContext->min_y = min(globalContext->min_y, globalContext->pLocalContext[j]->min_y); globalContext->max_x = max(globalContext->max_x, globalContext->pLocalContext[j]->max_x); globalContext->max_y = max(globalContext->max_y, globalContext->pLocalContext[j]->max_y); }; tree.init(globalContext->min_x, globalContext->min_y, globalContext->max_x, globalContext->max_y); globalContext->coolDown *= 0.999f; tree.clear(); }; // wait because the morton number computation needs the bounding box sync(); // udpate morton number to prepare them for sorting for_loop(pointPartition, LQMortonFunctor(localContext)); // wait so we can sort them by morton number sync(); #ifdef OGDF_FME_PARALLEL_QUADTREE_SORT // use a simple parallel sorting algorithm LinearQuadtree::LQPoint* points = tree.pointArray(); sort_parallel(points, tree.numberOfPoints(), LQPointComparer); #else if (isMainThread()) { LinearQuadtree::LQPoint* points = tree.pointArray(); sort_single(points, tree.numberOfPoints(), LQPointComparer); }; #endif // wait because the quadtree builder needs the sorted order sync(); // if not a parallel run, we can do the easy way if (isSingleThreaded()) { LinearQuadtreeBuilder builder(tree); // prepare the tree builder.prepareTree(); // and link it builder.build(); LQPartitioner partitioner( localContext ); partitioner.partition(); } else // the more difficult part { // snap the left point of the interval of the thread to the first in the cell LinearQuadtree::PointID beginPoint = tree.findFirstPointInCell(pointPartition.begin); LinearQuadtree::PointID endPoint_plus_one; // if this thread is the last one, no snapping required for the right point if (threadNr()==numThreads()-1) endPoint_plus_one = tree.numberOfPoints(); else // find the left point of the next thread endPoint_plus_one = tree.findFirstPointInCell(pointPartition.end+1); // and calculate the number of points to prepare __uint32 numPointsToPrepare = endPoint_plus_one - beginPoint; // now we can prepare the snapped interval LinearQuadtreeBuilder builder(tree); // this function prepares the tree from begin point to endPoint_plus_one-1 (EXCLUDING endPoint_plus_one) builder.prepareTree(beginPoint, endPoint_plus_one); // save the start, end and count of the inner node chain in the context localContext->firstInnerNode = builder.firstInner; localContext->lastInnerNode = builder.lastInner; localContext->numInnerNodes = builder.numInnerNodes; // save the start, end and count of the leaf node chain in the context localContext->firstLeaf = builder.firstLeaf; localContext->lastLeaf = builder.lastLeaf; localContext->numLeaves = builder.numLeaves; // wait until all are finished sync(); // now the main thread has to link the tree if (isMainThread()) { // with his own builder LinearQuadtreeBuilder sbuilder(tree); // first we need the complete chain data sbuilder.firstInner = globalContext->pLocalContext[0]->firstInnerNode; sbuilder.firstLeaf = globalContext->pLocalContext[0]->firstLeaf; sbuilder.numInnerNodes = globalContext->pLocalContext[0]->numInnerNodes; sbuilder.numLeaves = globalContext->pLocalContext[0]->numLeaves; for (__uint32 j=1; j < numThreads(); j++) { sbuilder.numLeaves += globalContext->pLocalContext[j]->numLeaves; sbuilder.numInnerNodes += globalContext->pLocalContext[j]->numInnerNodes; }; sbuilder.lastInner = globalContext->pLocalContext[numThreads()-1]->lastInnerNode; sbuilder.lastLeaf = globalContext->pLocalContext[numThreads()-1]->lastLeaf; // Link the tree sbuilder.build(); // and run the partitions LQPartitioner partitioner(localContext); partitioner.partition(); }; }; // wait for tree to finish sync(); // now update the copy of the point data for_loop(pointPartition, LQPointUpdateFunctor(localContext)); // compute the nodes coordinates and sizes tree.forall_tree_nodes(LQCoordsFunctor(localContext), localContext->innerNodePartition.begin, localContext->innerNodePartition.numNodes)(); tree.forall_tree_nodes(LQCoordsFunctor(localContext), localContext->leafPartition.begin, localContext->leafPartition.numNodes)(); };