Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <fcntl.h>
- #include <io.h>
- #include <stdio.h>
- #include <iostream>
- #include <stdlib.h>
- #include <sys/stat.h>
- /*
- В общем идея примерно такая: делим левую матрицу на блоки из нескольких строк ("режем по строкам"),
- а вторую - на блоки из нескольких столбцов ("режем по столбцам").
- Так как матрицы записаны построчно, эффективнее прочитать один раз столбцы, а для них
- каждый раз считать строки.
- Ну вот так примерно и происходит:
- считываем блок столбцов правой матрицы (read_columns),
- считываем блок строк левой матрицы (read_rows),
- перемножаем (multiply_addition),
- и записываем результат в нужное место (write_block)
- Честно говоря не могу сказать, почему block_size = 100)
- Я когда сдавал, просто подбирал
- */
- const int block_size = 100;
- void multiply_addition(char *result_matrix_buffer, char *first_matrix_buffer, char *second_matrix_buffer,
- int first_matrix_row_size, int second_matrix_column_size, int matrix_size) {
- for (int row_cunter = 0; row_cunter < first_matrix_row_size; ++row_cunter) {
- for (int column_counter = 0; column_counter < second_matrix_column_size; ++column_counter) {
- char sum = 0;
- for (int k = 0; k < matrix_size; ++k) {
- sum += first_matrix_buffer[row_cunter* matrix_size + k] *
- second_matrix_buffer[k * second_matrix_column_size + column_counter];
- }
- result_matrix_buffer[row_cunter* second_matrix_column_size + column_counter] = sum;
- }
- }
- }
- void read_rows(int input_file_desctriptor, char* buffer, int matrix_size, int row_block_counter, int row_number) {
- int start_position = 8 + row_block_counter * matrix_size * block_size;
- _lseek(input_file_desctriptor, start_position, 0);
- _read(input_file_desctriptor, buffer, matrix_size * row_number);
- }
- void read_columns(int input_file_desctriptor, char* second_matrix_buffer, int matrix_size, int column_block_counter,
- int second_matrix_column_number, int offset) {
- int start_position = offset + column_block_counter * block_size;
- for (int column_count = 0; column_count < matrix_size; ++column_count) {
- _lseek(input_file_desctriptor, start_position, 0);
- _read(input_file_desctriptor, second_matrix_buffer + column_count * second_matrix_column_number, second_matrix_column_number);
- start_position += matrix_size;
- }
- }
- void write_block(int output_file_desctriptor, char* result_buffer, int matrix_size, int row_block_counter, int column_block_counter,
- int result_matrix_row_number, int result_matrix_column_number) {
- int start_position = 8 + row_block_counter* block_size * matrix_size + column_block_counter * block_size;
- for (int i = 0; i < result_matrix_row_number; ++i) {
- _lseek(output_file_desctriptor, start_position, 0);
- _write(output_file_desctriptor, result_buffer + i * result_matrix_column_number, result_matrix_column_number);
- start_position += matrix_size;
- }
- }
- void multiply(int input_file_desctriptor, int output_file_dectriptor) {
- char size_buf[4];
- _read(input_file_desctriptor, size_buf, 4);
- const int matrix_size = *reinterpret_cast<int*>(size_buf);
- _write(output_file_dectriptor, size_buf, 4);
- _write(output_file_dectriptor, size_buf, 4);
- char * first_matrix_buffer = new char[block_size * matrix_size];
- char * second_matrix_buffer = new char[matrix_size * block_size];
- char * result_buffer = new char[block_size * block_size];
- const int block_number = matrix_size / block_size;
- const int last_block_size = matrix_size % block_size;
- const int iterations_number = block_number + (last_block_size > 0 ? 1 : 0);
- for (int column_block_counter = 0; column_block_counter < iterations_number; ++column_block_counter) {
- int result_matrix_column_number = (column_block_counter < block_number) ? block_size : last_block_size;
- read_columns(input_file_desctriptor, second_matrix_buffer, matrix_size,
- column_block_counter, result_matrix_column_number, 16 + matrix_size * matrix_size);
- for (int row_block_counter = 0; row_block_counter < iterations_number; ++row_block_counter) {
- int result_matrix_row_number = (row_block_counter < block_number)? block_size: last_block_size;
- read_rows(input_file_desctriptor, first_matrix_buffer, matrix_size, row_block_counter, result_matrix_row_number);
- multiply_addition(result_buffer, first_matrix_buffer, second_matrix_buffer,
- result_matrix_row_number, result_matrix_column_number, matrix_size);
- write_block(output_file_dectriptor, result_buffer, matrix_size, row_block_counter, column_block_counter,
- result_matrix_row_number, result_matrix_column_number);
- }
- }
- delete[] first_matrix_buffer;
- delete[] second_matrix_buffer;
- delete[] result_buffer;
- }
- int main() {
- const int input_fd = _open("input.bin", _O_RDONLY | _O_BINARY | _O_RANDOM, _S_IREAD);
- const int output_file_dectriptor =
- _open("output.bin", _O_CREAT | _O_TRUNC | _O_WRONLY | _O_BINARY | _O_RANDOM, _S_IWRITE);
- multiply(input_fd, output_file_dectriptor);
- _close(output_file_dectriptor);
- _close(input_fd);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement