'''[https://github.com/vitokhangnguyen/WebWorkerDemo/blob/main/scripts/dedicated.js dedicated.js]'''
INSERT CODE HERE <pre>function performParallelSobel(WITH COMMENTS){ // Reset canvas const tempContext = parallelCanvas.getContext("2d"); tempContext.drawImage(image, 0, 0); // Check if web workers are compatible (All browsers that follow HTML5 standards are compatible) if (window.Worker) { // Record starting time let start = window.performance.now(); let end; const numOfWorkers = slider.value; let finished = 0; // Height of the picture chunck for every worker const blockSize = parallelCanvas.height / numOfWorkers; // Function called when a worker has finished let onWorkEnded = function (e) { // Data is retrieved using a memory clone operation const sobelData = e.data.result; const index = e.data.index; // Copy sobel data to the canvas let sobelImageData = Sobel.toImageData(sobelData, parallelCanvas.width, blockSize); tempContext.putImageData(sobelImageData, 0, blockSize * index); finished++; if (finished == numOfWorkers) { // Calculate Time difference end = window.performance.now(); const difference = `${end-start} ms`; parallelResults.textContent = difference; const color = '#' + Math.floor(Math.random() * 16777215).toString(16); // Update chart updateChart(numOfWorkers, end - start, color, `Parallel (${numOfWorkers})`); } }; // Launch n numbers of workers for (let i = 0; i < numOfWorkers; i++) { // Create a web worker object by passing in the file consisting of code to execute in parallel const worker = new Worker('./scripts/dedicatedWorker.js'); // Once the worker has completed, execute onWorkEnded function worker.onmessage = onWorkEnded; // Break image into chunks using the blocksize const canvasData = tempContext.getImageData(0, blockSize * i, parallelCanvas.width, blockSize); // Start Working - (launch the thread) worker.postMessage({ data: canvasData, // Thread ID index: i, }); } }}</pre>
Now running the Sobel filter on a separate thread allows us to continue interacting with the UI but, the execution time slightly increased. This is because we have to instantiate the worker, which takes time and resources. Luckily, we can drastically improve the Sobel filtering process by breaking the image down into horizontal chunks. We do this by getting the height and dividing by the number of processors allowed by the browser, which is obtained using the Windows API (''window.navigator.hardwareConcurrency''). Once we chunk the image, we can create ''n'' number of worker objects based on the hardware concurrency set by the browser and post the chunk of data to them with their ID (''index''). When a worker is finished running, it will send a response using the ''onmesasge'' event handler, so we can assign a function to be executed when the event is triggered. In the file, we passed into the web worker constructor, we refer to the global scope using self and call the ''onmessage'' event handler. This event handler receives the posted data we sent from dedicated.js and initiates the Sobel filtering. Once the filtering is done, the data is posted back by referring to self.