fork download
  1. #include <iostream>
  2. #include <vector>
  3. #include <thread>
  4. #include <chrono>
  5. #include <mutex>
  6. #include <cstdlib>
  7. #include <ctime>
  8.  
  9. using namespace std;
  10.  
  11. mutex print_mutex;
  12.  
  13. void multiply_part(const vector<vector<float>>& A,
  14. const vector<vector<float>>& B_T,
  15. vector<vector<float>>& C,
  16. int start_row, int end_row,
  17. int thread_id) {
  18. int n = A.size();
  19.  
  20. for (int i = start_row; i < end_row; i++) {
  21. for (int k = 0; k < n; k++) {
  22. float aik = A[i][k];
  23. if (aik != 0.0f) {
  24. for (int j = 0; j < n; j++) {
  25. C[i][j] += aik * B_T[k][j];
  26. }
  27. }
  28. }
  29. }
  30.  
  31. lock_guard<mutex> lock(print_mutex);
  32. cout << "Поток " << thread_id << " завершил строки " << start_row << "-" << end_row << endl;
  33. }
  34.  
  35. int main() {
  36. const int SIZE = 64; // 64x64 (маленький, для онлайн-компилятора)
  37. const int THREADS = 4; // 4 потока
  38.  
  39. cout << "Создание матриц " << SIZE << "x" << SIZE << "..." << endl;
  40.  
  41. // Создаём матрицы
  42. vector<vector<float>> A(SIZE, vector<float>(SIZE));
  43. vector<vector<float>> B(SIZE, vector<float>(SIZE));
  44. vector<vector<float>> C(SIZE, vector<float>(SIZE, 0.0f));
  45.  
  46. // Заполняем случайными числами
  47. srand(123);
  48. for (int i = 0; i < SIZE; i++) {
  49. for (int j = 0; j < SIZE; j++) {
  50. A[i][j] = (float)(rand() % 100) / 100.0f;
  51. B[i][j] = (float)(rand() % 100) / 100.0f;
  52. }
  53. }
  54.  
  55. // Транспонируем B для лучшей производительности
  56. cout << "Транспонирование матрицы B..." << endl;
  57. vector<vector<float>> B_T(SIZE, vector<float>(SIZE));
  58. for (int i = 0; i < SIZE; i++) {
  59. for (int j = 0; j < SIZE; j++) {
  60. B_T[j][i] = B[i][j];
  61. }
  62. }
  63.  
  64. // Запускаем потоки
  65. cout << "Запуск " << THREADS << " потоков..." << endl;
  66. vector<thread> threads;
  67. int rows_per_thread = SIZE / THREADS;
  68.  
  69. for (int t = 0; t < THREADS; t++) {
  70. int start_row = t * rows_per_thread;
  71. int end_row = (t == THREADS - 1) ? SIZE : (t + 1) * rows_per_thread;
  72.  
  73. threads.push_back(thread(multiply_part, ref(A), ref(B_T), ref(C),
  74. start_row, end_row, t));
  75. }
  76.  
  77. // Ждём завершения всех потоков
  78. for (auto& th : threads) {
  79. th.join();
  80. }
  81.  
  82. // Выводим результат
  83. cout << "\nРезультат умножения:" << endl;
  84. cout << "C[0][0] = " << C[0][0] << endl;
  85. cout << "C[0][1] = " << C[0][1] << endl;
  86. cout << "C[1][0] = " << C[1][0] << endl;
  87. cout << "C[63][63] = " << C[SIZE-1][SIZE-1] << endl;
  88.  
  89. cout << "\nГотово!" << endl;
  90.  
  91. return 0;
  92. }
Success #stdin #stdout 0.01s 5320KB
stdin
Standard input is empty
stdout
Создание матриц 64x64...
Транспонирование матрицы B...
Запуск 4 потоков...
Поток 3 завершил строки 48-64
Поток 2 завершил строки 32-48
Поток 1 завершил строки 16-32
Поток 0 завершил строки 0-16

Результат умножения:
C[0][0] = 17.8065
C[0][1] = 18.2589
C[1][0] = 16.8879
C[63][63] = 16.1421

Готово!