CopyPastor

Detecting plagiarism made easy.

Score: 1.8299479704839703; Reported for: String similarity, Exact paragraph match Open both answers

Possible Plagiarism

Reposted on 2024-03-31
by Alex Sokolek

Original Post

Original - Posted on 2024-03-31
by Alex Sokolek



            
Present in both answers; Present only in the new answer; Present only in the old answer;

I have a workoing multithreaded mandelbrot implementation. It breaks the workload up into between 1 and 64 threads. No mutex's are required. Here is the worker thread...
``` // Worker thread for processing the Mandelbrot algorithm DWORD WINAPI MandelbrotWorkerThread(LPVOID lpParam) { // This is a copy of the structure from the paint procedure. // The address of this structure is passed with lParam. typedef struct ThreadProcParameters { int StartPixel; int EndPixel; int yMaxPixel; int xMaxPixel; uint32_t* BitmapData; double dxMin; double dxMax; double dyMin; double dyMax; } THREADPROCPARAMETERS, *PTHREADPROCPARAMETERS; PTHREADPROCPARAMETERS P; P = (PTHREADPROCPARAMETERS)lpParam;
// Algorithm obtained from https://en.wikipedia.org/wiki/Mandelbrot_set.
double x0, y0, x, y, xtemp;
int iteration;
// Loop for each pixel in the slice. for (int Pixel = P->StartPixel; Pixel < P->EndPixel; ++Pixel) { // Calculate the x and y coordinates of the pixel. int xPixel = Pixel % P->xMaxPixel; int yPixel = Pixel / P->xMaxPixel;
// Calculate the real and imaginary coordinates of the point. x0 = (P->dxMax - P->dxMin) / P->xMaxPixel * xPixel + P->dxMin; y0 = (P->dyMax - P->dyMin) / P->yMaxPixel * yPixel + P->dyMin;
// Initial values. x = 0.0; y = 0.0; iteration = 0;
// Main Mandelbrot algorithm. Determine the number of iterations // that it takes each point to escape the distance of 2. The black // areas of the image represent the points that never escape. This // algorithm is supposed to be using complex arithmetic, but this // is a simplified separation of the real and imaginary parts of // the point's coordinate. This algorithm is described as the // naive "escape time algorithm" in the WikiPedia article noted.
while (x * x + y * y <= 2.0 * 2.0 && iteration < max_iterations) { xtemp = x * x - y * y + x0; y = 2 * x * y + y0; x = xtemp; ++iteration; }
// When we get here, we have a pixel and an iteration count. // Lookup the color in the spectrum of all colors and set the // pixel to that color. Note that we are only ever using 1000 // of the 16777215 possible colors. Changing max_iterations uses // a different pallette, but 1000 seems to be the best choice. // Note also that this bitmap is shared by all 64 threads, but // there is no concurrency conflict as each thread is assigned // a different region of the bitmap. The user has the option of // using the original RGB or the new and improved Log HSV system.
if (!bUseHSV) { // The old RGB system. P->BitmapData[Pixel] = ReverseRGBBytes ((COLORREF)(-16777215.0 / max_iterations * iteration + 16777215.0)); } else { // The new HSV system. sRGB rgb; sHSV hsv; hsv = mandelbrotHSV(iteration, max_iterations); rgb = hsv2rgb(hsv); P->BitmapData[Pixel] = (((int)(rgb.r * 255))) + (((int)(rgb.g * 255)) << 8) + (((int)(rgb.b * 255)) << 16 ); } } // End of thread execution. The return value is available // to the invoking thread, but we don't presently use it.
return 0; } ```
and here is the thread dispatcher...
``` // Parameters for each thread. typedef struct ThreadProcParameters { int StartPixel; int EndPixel; int yMaxPixel; int xMaxPixel; uint32_t* BitmapData; double dxMin; double dxMax; double dyMin; double dyMax; } THREADPROCPARAMETERS, *PTHREADPROCPARAMETERS;
// Allocate per thread parameter and handle arrays. PTHREADPROCPARAMETERS* pThreadProcParameters = new PTHREADPROCPARAMETERS[Slices]; HANDLE* phThreadArray = new HANDLE[Slices];
// MaxPixel is the total pixel count among all threads. int MaxPixel = (rect.bottom - tm.tmHeight) * rect.right; int StartPixel, EndPixel, Slice;
// Main thread dispatch loop. Walk the start and end pixel indices. for (StartPixel = 0, EndPixel = PixelStepSize, Slice = 0; (EndPixel <= MaxPixel) && (Slice < Slices); StartPixel += PixelStepSize, EndPixel = min(EndPixel + PixelStepSize, MaxPixel), ++Slice) { // Allocate the parameter structure for this thread. pThreadProcParameters[Slice] = (PTHREADPROCPARAMETERS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(THREADPROCPARAMETERS)); if (pThreadProcParameters[Slice] == NULL) ExitProcess(2);
// Initialize the parameters for this thread. pThreadProcParameters[Slice]->StartPixel = StartPixel; pThreadProcParameters[Slice]->EndPixel = EndPixel; pThreadProcParameters[Slice]->yMaxPixel = rect.bottom - tm.tmHeight; // Leave room for the status bar. pThreadProcParameters[Slice]->xMaxPixel = rect.right; pThreadProcParameters[Slice]->BitmapData = BitmapData; // Bitmap is shared among all threads. pThreadProcParameters[Slice]->dxMin = dxMin; pThreadProcParameters[Slice]->dxMax = dxMax; pThreadProcParameters[Slice]->dyMin = dyMin; pThreadProcParameters[Slice]->dyMax = dyMax;
// Create and launch this thread. phThreadArray[Slice] = CreateThread (NULL, 0, MandelbrotWorkerThread, pThreadProcParameters[Slice], 0, NULL); if (phThreadArray[Slice] == NULL) { ErrorHandler((LPTSTR)_T("CreateThread")); ExitProcess(3); } } // End of main thread dispatch loop.
// Wait for all threads to terminate. WaitForMultipleObjects(Slices, phThreadArray, TRUE, INFINITE);
// Deallocate the thread arrays and structures. for (Slice = 0; Slice < Slices; ++Slice) { CloseHandle(phThreadArray[Slice]); HeapFree(GetProcessHeap(), 0, pThreadProcParameters[Slice]); } delete[] phThreadArray; delete[] pThreadProcParameters;
// Refresh the image with the bitmap. SetDIBitsToDevice(hdc, 0, 0, rect.right, rect.bottom - tm.tmHeight, 0, 0, 0, rect.bottom - tm.tmHeight, BitmapData, &dbmi, 0); ```
If you want to see the whole program, perhaps to compile it and see how it does on your machine, please take a look at https://github.com/alexsokolek2/mandelbrot.
I have a multi-threaded implementation of Mandelbrot. Instead of scanning X and Y in nested loops, I scan pixels from 0 to width*height. The Mandelbrot worker thread then calculates the logical and real coordinates of the pixel. Here is a subset of the code...
``` // Worker thread for processing the Mandelbrot algorithm DWORD WINAPI MandelbrotWorkerThread(LPVOID lpParam) { // This is a copy of the structure from the paint procedure. // The address of this structure is passed with lParam. typedef struct ThreadProcParameters { int StartPixel; int EndPixel; int yMaxPixel; int xMaxPixel; uint32_t* BitmapData; double dxMin; double dxMax; double dyMin; double dyMax; } THREADPROCPARAMETERS, *PTHREADPROCPARAMETERS; PTHREADPROCPARAMETERS P; P = (PTHREADPROCPARAMETERS)lpParam;
// Algorithm obtained from https://en.wikipedia.org/wiki/Mandelbrot_set.
double x0, y0, x, y, xtemp;
int iteration;
// Loop for each pixel in the slice. for (int Pixel = P->StartPixel; Pixel < P->EndPixel; ++Pixel) { // Calculate the x and y coordinates of the pixel. int xPixel = Pixel % P->xMaxPixel; int yPixel = Pixel / P->xMaxPixel;
// Calculate the real and imaginary coordinates of the point. x0 = (P->dxMax - P->dxMin) / P->xMaxPixel * xPixel + P->dxMin; y0 = (P->dyMax - P->dyMin) / P->yMaxPixel * yPixel + P->dyMin;
// Initial values. x = 0.0; y = 0.0; iteration = 0;
// Main Mandelbrot algorithm. Determine the number of iterations // that it takes each point to escape the distance of 2. The black // areas of the image represent the points that never escape. This // algorithm is supposed to be using complex arithmetic, but this // is a simplified separation of the real and imaginary parts of // the point's coordinate. This algorithm is described as the // naive "escape time algorithm" in the WikiPedia article noted.
while (x * x + y * y <= 2.0 * 2.0 && iteration < max_iterations) { xtemp = x * x - y * y + x0; y = 2 * x * y + y0; x = xtemp; ++iteration; }
// When we get here, we have a pixel and an iteration count. // Lookup the color in the spectrum of all colors and set the // pixel to that color. Note that we are only ever using 1000 // of the 16777215 possible colors. Changing max_iterations uses // a different pallette, but 1000 seems to be the best choice. // Note also that this bitmap is shared by all 64 threads, but // there is no concurrency conflict as each thread is assigned // a different region of the bitmap. The user has the option of // using the original RGB or the new and improved Log HSV system.
if (!bUseHSV) { // The old RGB system. P->BitmapData[Pixel] = ReverseRGBBytes ((COLORREF)(-16777215.0 / max_iterations * iteration + 16777215.0)); } else { // The new HSV system. sRGB rgb; sHSV hsv; hsv = mandelbrotHSV(iteration, max_iterations); rgb = hsv2rgb(hsv); P->BitmapData[Pixel] = (((int)(rgb.r * 255))) + (((int)(rgb.g * 255)) << 8) + (((int)(rgb.b * 255)) << 16 ); } } // End of thread execution. The return value is available // to the invoking thread, but we don't presently use it.
return 0; ```
And this is the thread dispatcher...
``` // Parameters for each thread. typedef struct ThreadProcParameters { int StartPixel; int EndPixel; int yMaxPixel; int xMaxPixel; uint32_t* BitmapData; double dxMin; double dxMax; double dyMin; double dyMax; } THREADPROCPARAMETERS, *PTHREADPROCPARAMETERS;
// Allocate per thread parameter and handle arrays. PTHREADPROCPARAMETERS* pThreadProcParameters = new PTHREADPROCPARAMETERS[Slices]; HANDLE* phThreadArray = new HANDLE[Slices];
// MaxPixel is the total pixel count among all threads. int MaxPixel = (rect.bottom - tm.tmHeight) * rect.right; int StartPixel, EndPixel, Slice;
// Main thread dispatch loop. Walk the start and end pixel indices. for (StartPixel = 0, EndPixel = PixelStepSize, Slice = 0; (EndPixel <= MaxPixel) && (Slice < Slices); StartPixel += PixelStepSize, EndPixel = min(EndPixel + PixelStepSize, MaxPixel), ++Slice) { // Allocate the parameter structure for this thread. pThreadProcParameters[Slice] = (PTHREADPROCPARAMETERS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(THREADPROCPARAMETERS)); if (pThreadProcParameters[Slice] == NULL) ExitProcess(2);
// Initialize the parameters for this thread. pThreadProcParameters[Slice]->StartPixel = StartPixel; pThreadProcParameters[Slice]->EndPixel = EndPixel; pThreadProcParameters[Slice]->yMaxPixel = rect.bottom - tm.tmHeight; // Leave room for the status bar. pThreadProcParameters[Slice]->xMaxPixel = rect.right; pThreadProcParameters[Slice]->BitmapData = BitmapData; // Bitmap is shared among all threads. pThreadProcParameters[Slice]->dxMin = dxMin; pThreadProcParameters[Slice]->dxMax = dxMax; pThreadProcParameters[Slice]->dyMin = dyMin; pThreadProcParameters[Slice]->dyMax = dyMax;
// Create and launch this thread. phThreadArray[Slice] = CreateThread (NULL, 0, MandelbrotWorkerThread, pThreadProcParameters[Slice], 0, NULL); if (phThreadArray[Slice] == NULL) { ErrorHandler((LPTSTR)_T("CreateThread")); ExitProcess(3); } } // End of main thread dispatch loop.
// Wait for all threads to terminate. WaitForMultipleObjects(Slices, phThreadArray, TRUE, INFINITE); ```
This can be broken up into as many threads as desired. My program, for instance, allows between 1 and 64 threads. For the full program, see https://github.com/alexsokolek2/mandelbrot. Good luck.

        
Present in both answers; Present only in the new answer; Present only in the old answer;