Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include <windows.h>
- #include <thread>
- #include <iostream>
- #include <thread>
- #include <vector>
- #include <algorithm>
- #include <string>
- typedef int(__stdcall *AsmFunction)(int* tab, int size);
- typedef void(__stdcall *CppFunction)(int*, int);
- void loadData(unsigned char info[54], unsigned char* & data, int& numberOfElements, char* fileName) {
- FILE* file = fopen(fileName, "rb");
- if (file) {
- fread(info, sizeof(unsigned char), 54, file); // read the header
- //Extracting image height and width from the header
- int width = *(int*)&info[18];
- int height = *(int*)&info[22];
- width = width + (width % 4);
- //Calculating number of bytes required to store all BGR values
- numberOfElements = 3 * width * height;
- data = new unsigned char[numberOfElements];
- unsigned char* datatmp = new unsigned char[numberOfElements];
- fread(datatmp, sizeof(unsigned char), numberOfElements, file); // Reading the rest of the data at once
- for (int i = 0; i < numberOfElements; i++) {
- if (i % 3 == 0)
- data[(i / 3)] = datatmp[i];
- if (i % 3 == 1)
- data[(numberOfElements / 3) + (i / 3)] = datatmp[i];
- if (i % 3 == 2)
- data[2 * (numberOfElements / 3) + (i / 3)] = datatmp[i];
- }
- }
- }
- void func(char x)
- {
- std::cout << x;
- }
- void saveData(unsigned char info[54], unsigned char* & data, int& numberOfElements)
- {
- unsigned char* datatmp = new unsigned char[numberOfElements];
- for (int i = 0; i < numberOfElements / 3; i++) {
- datatmp[3 * i] = data[i];
- datatmp[3 * i + 1] = data[i + (numberOfElements / 3)];
- datatmp[3 * i + 2] = data[i + 2 * (numberOfElements / 3)];
- }
- data = datatmp;
- FILE* saveFile = fopen("Result.bmp", "wb");
- fwrite(info, sizeof(unsigned char), 54, saveFile);
- fwrite(data, sizeof(unsigned char), numberOfElements, saveFile);
- fclose(saveFile);
- }
- //argv[1] - file name, argv[2] - number of threads
- int main(int argc, char** argv) {
- if (argc != 3)
- return 0;
- //Loading functions
- HINSTANCE handleToAsmDll = LoadLibraryA("JADll");
- HINSTANCE handleToCppDll = LoadLibraryA("CPPDll");
- AsmFunction myAsmFunction;
- CppFunction myCppFunction;
- if (handleToAsmDll != NULL || handleToCppDll != NULL)
- {
- myAsmFunction = (AsmFunction)GetProcAddress(handleToAsmDll, "MyProc1");
- myCppFunction = (CppFunction)GetProcAddress(handleToCppDll, "decolorization");
- }
- else
- {
- return 0;
- }
- if (myAsmFunction == NULL || myCppFunction == NULL)
- {
- return 0;
- }
- //Checking number concurent threads supported (not number of cores)
- const int concurentThreadsSupported = std::thread::hardware_concurrency();
- int numberOfThreads = std::stoi(argv[2]);
- unsigned char* data;
- int numberOfElements;
- unsigned char info[54];
- //Loading data
- loadData(info, data, numberOfElements, argv[1]);
- int* data_int = new int[numberOfElements];
- for (int i = 0; i < numberOfElements; i++)
- data_int[i] = (int)data[i];
- //Creating vector of threads
- std::vector <std::thread> vectorOfThreads;
- //Calculating number of elements for each thread
- int elementsPerThread = ceil((double)numberOfElements / numberOfThreads);
- if (elementsPerThread % 3 == 2)
- elementsPerThread += 2;
- if (elementsPerThread % 3 == 1)
- elementsPerThread += 1;
- //Splitting data into smaller portions
- int** portionedData = new int*[numberOfThreads];
- for (int i = 0; i < numberOfThreads - 1; ++i)
- portionedData[i] = new int[elementsPerThread];
- portionedData[numberOfThreads - 1] = new int[numberOfElements - (elementsPerThread * (numberOfThreads - 1))];
- for (int j = 0; j < numberOfThreads - 1; j++) {
- for (int i = 0; i < elementsPerThread; i++) {
- /* if (i + j * elementsPerThread <= numberOfElements / 3)
- break;*/
- if (i % 3 == 0)
- portionedData[j][i / 3] = data_int[i/3 + (j * elementsPerThread) / 3];
- if (i % 3 == 1)
- portionedData[j][i / 3 + (elementsPerThread / 3)] = data_int[i/3 + (numberOfElements / 3) + (j * elementsPerThread) / 3];
- if (i % 3 == 2)
- portionedData[j][i / 3 + 2 * (elementsPerThread / 3)] = data_int[i/3 + 2 * (numberOfElements / 3) + (j * elementsPerThread) / 3];
- }
- }
- for (int i = 0; i < numberOfElements - (elementsPerThread * (numberOfThreads - 1)); i++) {
- if (i <= numberOfElements)
- break;
- if (i % 3 == 0)
- portionedData[numberOfThreads - 1][i / 3] = data_int[i / 3 + ((numberOfThreads - 1) * elementsPerThread) / 3];
- if (i % 3 == 1)
- portionedData[numberOfThreads - 1][i / 3 + (elementsPerThread / 3)] = data_int[i / 3 + (numberOfElements / 3) + ((numberOfThreads - 1) * elementsPerThread) / 3];
- if (i % 3 == 2)
- portionedData[numberOfThreads - 1][i / 3 + 2 * (elementsPerThread / 3)] = data_int[i / 3 + 2 * (numberOfElements / 3) + ((numberOfThreads - 1) * elementsPerThread) / 3];
- }
- std::chrono::steady_clock::duration time;
- auto start = std::chrono::steady_clock::now();
- ////Starting all threads but the last one
- //for (int i = 0; i < numberOfThreads - 1; i++)
- //{
- // std::thread thread(myCppFunction, portionedData[i + 1], elementsPerThread);
- // vectorOfThreads.push_back(std::move(thread)); //Thread can't be copied - has to be moved
- //}
- ////Starting last thread
- //std::thread thread(myCppFunction, portionedData[numberOfThreads - 1], numberOfElements - (elementsPerThread * (numberOfThreads - 1)));
- //vectorOfThreads.push_back(std::move(thread));
- ////Joining all threads
- //for (int i = 0; i < numberOfThreads - 1; i++)
- //{
- // vectorOfThreads.at(i).join();
- //}
- auto end = std::chrono::steady_clock::now();
- time = end - start;
- std::cout << std::chrono::duration_cast<std::chrono::microseconds>(time).count();
- for (int i = 0; i < numberOfThreads - 1; i++)
- myCppFunction(portionedData[i], elementsPerThread);
- myCppFunction(portionedData[numberOfThreads - 1], numberOfElements - (elementsPerThread * (numberOfThreads - 1)));
- for (int j = 0; j < numberOfThreads - 1; j++) {
- for (int i = 0; i < elementsPerThread; i++) {
- /* if (i + j * elementsPerThread <= numberOfElements / 3)
- break;*/
- if (i % 3 == 0)
- data_int[i / 3 + (j * elementsPerThread) / 3] = portionedData[j][i / 3];
- if (i % 3 == 1)
- data_int[i / 3 + (numberOfElements / 3) + (j * elementsPerThread) / 3] = portionedData[j][i / 3 + (elementsPerThread / 3)];
- if (i % 3 == 2)
- data_int[i / 3 + 2 * (numberOfElements / 3) + (j * elementsPerThread) / 3] = portionedData[j][i / 3 + 2 * (elementsPerThread / 3)];
- }
- }
- for (int i = 0; i < numberOfElements - (elementsPerThread * (numberOfThreads - 1)); i++) {
- if (i % 3 == 0)
- data_int[i / 3 + ((numberOfThreads - 1) * elementsPerThread) / 3] = portionedData[numberOfThreads - 1][i / 3];
- if (i % 3 == 1)
- data_int[i / 3 + (numberOfElements / 3) + ((numberOfThreads - 1) * elementsPerThread) / 3] = portionedData[numberOfThreads - 1][i / 3 + (elementsPerThread / 3)];
- if (i % 3 == 2)
- data_int[i / 3 + 2 * (numberOfElements / 3) + ((numberOfThreads - 1) * elementsPerThread) / 3] = portionedData[numberOfThreads - 1][i / 3 + 2 * (elementsPerThread / 3)];
- }
- //myAsmFunction(data_int, numberOfElements);
- //myCppFunction(data_int, numberOfElements);
- for (int i = 0; i < numberOfElements; i++)
- data[i] = (unsigned char)data_int[i];
- saveData(info, data, numberOfElements);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement