并行手册
The static classes maxon::ParallelFor , maxon::ParallelImage and maxon::ParallelInvoke are used to execute parallelized code.
The maxon::ParallelFor class is used to execute code defined in a worker method. This code is executed in a loop distributed over multiple threads. The workload is distributed either dynamically or statically.
// array that stores the inside/outside state for each generated point // ParallelFor will write into this array from multiple threads simultaneously maxon::BaseArray<maxon::Bool> pointStates; pointStates. Resize (count) iferr_return ;
// create random point maxon::LinearCongruentialRandom<maxon::Float32> random; random. Init ( maxon::UInt32 (i));
// check if inside circle if (point. GetSquaredLength () < 1.0) pointStates[i] = true ; };
// generate and check random points maxon::ParallelFor::Dynamic (0, count, worker);
// get pi maxon::Int64 insideCount = 0; for ( const maxon::Bool pointInside : pointStates) { if (pointInside) insideCount++; } const maxon::Float pi = 4.0 * maxon::Float (insideCount) / maxon::Float (count); DiagnosticOutput ( "PI approximation: @" , pi);
maxon::ParallelFor::BreakContext is a base class to define a context for maxon::ParallelFor loops that support cancellation. A class based on maxon::ParallelFor::BreakContext stores the data handled in a thread.
maxon::ParallelFor can call additional "Init" and "Finalize" functions for each thread. The behaviour is defined with these flags:
// total number inside the unit-circle maxon::Int insideCount = 0;
// data structure struct LocalData : public maxon::ParallelFor::BreakContext { maxon::Int localCount; // number of points inside the unit-circle };
// init thread (called threaded) auto init = [](LocalData& context) { context.localCount = 0; };
// worker auto worker = []( maxon::Int i, LocalData& context) { maxon::LinearCongruentialRandom<maxon::Float32> random; random. Init ( maxon::UInt32 (i)); maxon::Vector2d64 point; point. x = random. Get01 (); point. y = random. Get01 (); if (point. GetSquaredLength () < 1.0) context.localCount++; };
// finalize thread (called synchronously) auto finalize = [&insideCount](LocalData& context) { // get total number of points inside the unit-circle insideCount += context.localCount; };
// run parallel code maxon::ParallelFor::Dynamic<LocalData, maxon::PARALLELFORFLAGS::INITTHREADED_FINALIZESYNC>(0, count, init, worker, finalize) iferr_return ;
// get pi const maxon::Float pi = 4.0 * maxon::Float (insideCount) / maxon::Float (count); DiagnosticOutput ( "PI approximation: @" , pi);
maxon::ParallelImage is a special class to process image data of a given size per pixel.
// allocate bitmap AutoAlloc<BaseBitmap> bitmap; if (bitmap == nullptr ) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION );
// define bitmap size const maxon::Int width = 1024; const maxon::Int height = 1024; const IMAGERESULT res = bitmap-> Init (width, height, 24); if (res != IMAGERESULT::OK ) return maxon::OutOfMemoryError( MAXON_SOURCE_LOCATION );
// dimensions as float values const maxon::Float widthF = maxon::Float (width); const maxon::Float heightF = maxon::Float (height); auto worker = [widthF, heightF, &bitmap]( maxon::Int x, maxon::Int y) { // get UV coords for the given pixel const maxon::Float xf = maxon::Float (x); const maxon::Float yf = maxon::Float (y); const maxon::Float u = xf / widthF; const maxon::Float v = yf / heightF;
// set colors based on UV coords const maxon::Int32 red = maxon::SafeConvert<maxon::Int32>(u * 255.9); const maxon::Int32 green = maxon::SafeConvert<maxon::Int32>(v * 255.9); const maxon::Int32 blue = 0;
// store color in the bitmap bitmap-> SetPixel ( Int32 (x), Int32 (y), red, green, blue); };
// process every pixel of the given bitmap maxon::ParallelImage::Process (width, height, 30, worker); ShowBitmap (bitmap);
The maxon::ParallelInvoke function can be used to execute multiple arbitrary functions in parallel.
// min/max values maxon::Float minA = 0.0, maxA = 0.0, minB = 0.0, maxB = 0.0;
// search for min/max values in the given arrays // GetMinMax() is a custom function maxon::ParallelInvoke ( true , [&arrayA, &minA, &maxA] { GetMinMax(arrayA, minA, maxA); }, [&araryB, &minB, &maxB] { GetMinMax(araryB, minB, maxB); } ) iferr_return ;
// check min/max values if ((minA > minB) && (maxA < maxB)) DiagnosticOutput ( "Min/max values of a array A are within the min/max values of array B" _s);