diff --git a/Makefile b/Makefile index 7660fb2..a821cf4 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ PROJECT = editBMP CXX = g++ -CXXFLAGS = -Isrc -std=c++17 -Werror -Wpedantic -Wall -g -fPIC +CXXFLAGS = -Isrc -std=c++17 -Wall -fopenmp SRC_DIR = src IMAGES_DIR = images @@ -13,9 +13,7 @@ OBJS = $(patsubst $(SRC_DIR)/%.cpp, %.o, $(SRCS)) default: all -all: $(PROJECT) images - -images: +all: $(PROJECT) mkdir -p $(IMAGES_DIR) %.o: $(SRC_DIR)/%.cpp $(DEPS) @@ -23,7 +21,7 @@ images: $(PROJECT): $(OBJS) $(CXX) -o $@ $^ $(CXXFLAGS) - + clean: rm -f *.o rm -f $(PROJECT) diff --git a/PerformReport.md b/PerformReport.md new file mode 100644 index 0000000..72de20e --- /dev/null +++ b/PerformReport.md @@ -0,0 +1,18 @@ +# Performance Report + + +### Test Configuration +- **CPU**: 6-core processor +- **Test Image**: 3840x2160 pixels +- **Threads**: 6 worker threads +- **Gaussian Kernel**: 25×25 (sigma = 1487,5) + + +| Operation | Single-Thread* | Multi-Thread** | Speedup | +|--------------------|----------------|----------------|---------| +| Clockwise | 231,00 ms | 49,66 ms | 4,65x | +| Counter-clockwise | 201,00 ms | 47,33 ms | 4,24x | +| Gaussian Filter | 85297,66 ms | 19038,33 ms | 4,48x | + +*Is calculated as an average of three runs of condition stored in the main branch +**Is calculated as an average of three runs of condition stored in current branch diff --git a/src/GaussFiltr.cpp b/src/GaussFiltr.cpp index 1915d0a..a43fcd3 100644 --- a/src/GaussFiltr.cpp +++ b/src/GaussFiltr.cpp @@ -7,6 +7,9 @@ #include #include +#include + + void BMP::GaussFiltr(int kernelSize) { auto start = std::chrono::high_resolution_clock::now(); @@ -16,6 +19,7 @@ void BMP::GaussFiltr(int kernelSize) std::vector> ratio(kernelSize, std::vector(kernelSize)); double sum = 0.0; + // Вычисление ядра фильтра (последовательно) for (int x = 0; x < kernelSize; x++) { for (int y = 0; y < kernelSize; y++) @@ -28,6 +32,8 @@ void BMP::GaussFiltr(int kernelSize) sum += GaussFun; } } + + // Нормализация ядра for (int x = 0; x < kernelSize; x++) { for (int y = 0; y < kernelSize; y++) @@ -35,18 +41,20 @@ void BMP::GaussFiltr(int kernelSize) ratio[x][y] /= sum; } } - std::vector new_data(data); // Инициализация копией исходных данных + + std::vector new_data(data); - for (int i = kernelSize / 2; i <= bmp_info_header.width - kernelSize / 2; i++) + // Параллелизация применения фильтра + #pragma omp parallel for + for (int j = kernelSize / 2; j <= bmp_info_header.height - kernelSize / 2; j++) { - for (int j = kernelSize / 2; j <= bmp_info_header.height - kernelSize / 2; j++) + for (int i = kernelSize / 2; i <= bmp_info_header.width - kernelSize / 2; i++) { float blueSum = 0, greenSum = 0, redSum = 0; for (int k = 0; k < kernelSize; k++) { for (int l = 0; l < kernelSize; l++) { - // Исправление индексации: k - вертикаль, l - горизонталь int x_index = i + l - kernelSize / 2; int y_index = j + k - kernelSize / 2; int pixelIndex = (y_index * bmp_info_header.width + x_index) * 3; @@ -64,7 +72,6 @@ void BMP::GaussFiltr(int kernelSize) } data.swap(new_data); - auto end = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast(end - start); std::cout << "Gaussian filter time: " << duration.count() << " ms" << std::endl; diff --git a/src/Rotate.cpp b/src/Rotate.cpp index 86abc15..4386a61 100644 --- a/src/Rotate.cpp +++ b/src/Rotate.cpp @@ -6,6 +6,8 @@ #include #include +#include + void BMP::clockwiseRotate() { @@ -16,18 +18,18 @@ void BMP::clockwiseRotate() std::vector new_data(new_width * new_height * 3); + // Параллелизация вращения + #pragma omp parallel for for (int y = 0; y < bmp_info_header.height; ++y) { for (int x = 0; x < bmp_info_header.width; ++x) { int old_index = (y * bmp_info_header.width + x) * 3; - int new_x, new_y; new_x = y; new_y = new_height - 1 - x; - int new_index = (new_y * new_width + new_x) * 3; new_data[new_index] = data[old_index]; @@ -54,18 +56,18 @@ void BMP::CounterClockwiseRotate() std::vector new_data(new_width * new_height * 3); + // Параллелизация вращения + #pragma omp parallel for for (int y = 0; y < bmp_info_header.height; ++y) { for (int x = 0; x < bmp_info_header.width; ++x) { int old_index = (y * bmp_info_header.width + x) * 3; - int new_x, new_y; new_x = new_width - 1 - y; new_y = x; - int new_index = (new_y * new_width + new_x) * 3; new_data[new_index] = data[old_index];