Помогите пожалуйста решить задачу, буду благодарен
Написать программу в C++
Сгенерировать два вектора одинаковой длины и вычислить, используя потоки, скалярное произведение. Расчеты проведете на четырех, восьми и шестнадцати. Подсчитаете эффективность и ускорение вычислений. На одном потоке программа должна работать 3-4 секунды, соответственно, выбирайте большую размерность вектора.
Комментарии к заданию:
В программе ничего не вводится. Сразу прописывайте размерность массивов. Программа на одном потоке должна считать 3-4 секунды. Время выдавать в секундах и три знака миллисекунд
Исходные данные для задания многопоточно генерируем, считать время не нужно, количество потоков - количество ядер в вашей системе.
Расчет эффективности = Ускорение / количество потоков.
Вот пример программы на C++, которая генерирует два вектора заданной длины, вычисляет скалярное произведение с помощью потоков и выводит на экран время работы, эффективность и ускорение:
#include <iostream>
#include <vector>
#include <chrono>
#include <thread>
using namespace std;
// Функция, вычисляющая скалярное произведение векторов
double dot_product(const vector<double>& a, const vector<double>& b)
{
double result = 0.0;
for (size_t i = 0; i < a.size(); ++i) {
result += a[i] * b[i];
}
return result;
}
int main()
{
const size_t size = 10000000; // Длина векторов
vector<double> a(size);
vector<double> b(size);
// Генерация случайных значений векторов
for (size_t i = 0; i < size; ++i) {
a[i] = static_cast<double>(rand()) / RAND_MAX;
b[i] = static_cast<double>(rand()) / RAND_MAX;
}
// Вычисление скалярного произведения на 1, 2, и 4 потоках
for (int num_threads = 1; num_threads <= 4; num_threads *= 2) {
cout << "Number of threads: " << num_threads << endl;
auto start_time = chrono::high_resolution_clock::now();
double result = 0.0;
vector<thread> threads(num_threads);
for (int i = 0; i < num_threads; ++i) {
threads[i] = thread([&a, &b, num_threads, i, &result]() {
const size_t chunk_size = a.size() / num_threads;
const size_t start = i * chunk_size;
const size_t end = (i == num_threads - 1) ? a.size() : (i + 1) * chunk_size;
double local_result = 0.0;
for (size_t j = start; j < end; ++j) {
local_result += a[j] * b[j];
}
result += local_result;
});
}
for (auto& t : threads) {
t.join();
}
auto end_time = chrono::high_resolution_clock::now();
chrono::duration<double, milli> elapsed_time = end_time - start_time;
cout << "Elapsed time: " << elapsed_time.count() / 1000.0 << " s" << endl;
double efficiency = elapsed_time.count() / (size * log2(num_threads) * 4.0);
cout << "Efficiency: " << efficiency << endl;
double speedup = elapsed_time.count() / (num_threads == 1 ? 3.0 : (elapsed_time.count() / 3.0));
cout << "Speedup: " << speedup << endl;
cout << endl;
}
return 0;
}
#include <iostream>
#include <vector>
#include <chrono>
#include <random>
#include <omp.h>
// Функция для генерации случайных чисел в указанном диапазоне
double generate_random_number(double min, double max)
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<> dis(min, max);
return dis(gen);
}
// Функция для вычисления скалярного произведения векторов
double scalar_product(const std::vector<double>& a, const std::vector<double>& b)
{
double result = 0.0;
#pragma omp parallel for reduction(+:result)
for (size_t i = 0; i < a.size(); ++i)
{
result += a[i] * b[i];
}
return result;
}
int main()
{
// Задаем размерность векторов
size_t vector_size = 10000000;
// Генерируем два вектора с случайными значениями
std::vector<double> vector1(vector_size);
std::vector<double> vector2(vector_size);
for (size_t i = 0; i < vector_size; ++i)
{
vector1[i] = generate_random_number(1.0, 10.0);
vector2[i] = generate_random_number(1.0, 10.0);
}
// Вычисляем скалярное произведение на одном потоке
double start_time = omp_get_wtime();
double scalar_product_single_thread = scalar_product(vector1, vector2);
double end_time = omp_get_wtime();
double time_single_thread = end_time - start_time;
// Вычисляем скалярное произведение на многопоточности с количеством потоков равным количеству ядер
int num_threads = omp_get_num_procs();
start_time = omp_get_wtime();
double scalar_product_multithread = scalar_product(vector1, vector2);
end_time = omp_get_wtime();
double time_multithread = end_time - start_time;
// Вычисляем эффективность и ускорение
double efficiency = time_single_thread / (time_multithread / num_threads);
double speedup = time_single_thread / time_multithread;
// Выводим результаты
std::cout << "Vector size: " << vector_size << std::endl;
std::cout << "Time on single thread: " << std::fixed << time_single_thread << " seconds" << std::endl;
std::cout << "Time on " << num_threads << " threads: " << std::fixed << time_multithread << " seconds" << std::endl;
std::cout << "Efficiency: " << std::fixed << efficiency << std::endl;
std::cout << "Speedup: " << std::fixed << speedup << std::endl;
return 0;