Cara: Menulis perulangan parallel_for
Contoh ini menunjukkan cara menggunakan konkurensi::p arallel_for untuk menghitung produk dari dua matriks.
Contoh: Menghitung produk dari dua matriks
Contoh berikut menunjukkan matrix_multiply
fungsi , yang menghitung produk dari dua matriks persegi.
// Computes the product of two square matrices.
void matrix_multiply(double** m1, double** m2, double** result, size_t size)
{
for (size_t i = 0; i < size; i++)
{
for (size_t j = 0; j < size; j++)
{
double temp = 0;
for (int k = 0; k < size; k++)
{
temp += m1[i][k] * m2[k][j];
}
result[i][j] = temp;
}
}
}
Contoh: Menghitung matriks mengalikan secara paralel
Contoh berikut menunjukkan parallel_matrix_multiply
fungsi , yang menggunakan parallel_for
algoritma untuk melakukan perulangan luar secara paralel.
// Computes the product of two square matrices in parallel.
void parallel_matrix_multiply(double** m1, double** m2, double** result, size_t size)
{
parallel_for (size_t(0), size, [&](size_t i)
{
for (size_t j = 0; j < size; j++)
{
double temp = 0;
for (int k = 0; k < size; k++)
{
temp += m1[i][k] * m2[k][j];
}
result[i][j] = temp;
}
});
}
Contoh ini memparalelkan perulangan luar hanya karena melakukan pekerjaan yang cukup untuk mendapatkan manfaat dari overhead untuk pemrosesan paralel. Jika Anda menyejajarkan perulangan dalam, Anda tidak akan menerima perolehan performa karena sedikit pekerjaan yang dilakukan perulangan dalam tidak mengatasi overhead untuk pemrosesan paralel. Oleh karena itu, hanya paralelisasi perulangan luar adalah cara terbaik untuk memaksimalkan manfaat konkurensi pada sebagian besar sistem.
Contoh: Sampel kode perulangan parallel_for selesai
Contoh yang lebih lengkap berikut membandingkan matrix_multiply
performa fungsi versus parallel_matrix_multiply
fungsi.
// parallel-matrix-multiply.cpp
// compile with: /EHsc
#include <windows.h>
#include <ppl.h>
#include <iostream>
#include <random>
using namespace concurrency;
using namespace std;
// Calls the provided work function and returns the number of milliseconds
// that it takes to call that function.
template <class Function>
__int64 time_call(Function&& f)
{
__int64 begin = GetTickCount();
f();
return GetTickCount() - begin;
}
// Creates a square matrix with the given number of rows and columns.
double** create_matrix(size_t size);
// Frees the memory that was allocated for the given square matrix.
void destroy_matrix(double** m, size_t size);
// Initializes the given square matrix with values that are generated
// by the given generator function.
template <class Generator>
double** initialize_matrix(double** m, size_t size, Generator& gen);
// Computes the product of two square matrices.
void matrix_multiply(double** m1, double** m2, double** result, size_t size)
{
for (size_t i = 0; i < size; i++)
{
for (size_t j = 0; j < size; j++)
{
double temp = 0;
for (int k = 0; k < size; k++)
{
temp += m1[i][k] * m2[k][j];
}
result[i][j] = temp;
}
}
}
// Computes the product of two square matrices in parallel.
void parallel_matrix_multiply(double** m1, double** m2, double** result, size_t size)
{
parallel_for (size_t(0), size, [&](size_t i)
{
for (size_t j = 0; j < size; j++)
{
double temp = 0;
for (int k = 0; k < size; k++)
{
temp += m1[i][k] * m2[k][j];
}
result[i][j] = temp;
}
});
}
int wmain()
{
// The number of rows and columns in each matrix.
// TODO: Change this value to experiment with serial
// versus parallel performance.
const size_t size = 750;
// Create a random number generator.
mt19937 gen(42);
// Create and initialize the input matrices and the matrix that
// holds the result.
double** m1 = initialize_matrix(create_matrix(size), size, gen);
double** m2 = initialize_matrix(create_matrix(size), size, gen);
double** result = create_matrix(size);
// Print to the console the time it takes to multiply the
// matrices serially.
wcout << L"serial: " << time_call([&] {
matrix_multiply(m1, m2, result, size);
}) << endl;
// Print to the console the time it takes to multiply the
// matrices in parallel.
wcout << L"parallel: " << time_call([&] {
parallel_matrix_multiply(m1, m2, result, size);
}) << endl;
// Free the memory that was allocated for the matrices.
destroy_matrix(m1, size);
destroy_matrix(m2, size);
destroy_matrix(result, size);
}
// Creates a square matrix with the given number of rows and columns.
double** create_matrix(size_t size)
{
double** m = new double*[size];
for (size_t i = 0; i < size; ++i)
{
m[i] = new double[size];
}
return m;
}
// Frees the memory that was allocated for the given square matrix.
void destroy_matrix(double** m, size_t size)
{
for (size_t i = 0; i < size; ++i)
{
delete[] m[i];
}
delete m;
}
// Initializes the given square matrix with values that are generated
// by the given generator function.
template <class Generator>
double** initialize_matrix(double** m, size_t size, Generator& gen)
{
for (size_t i = 0; i < size; ++i)
{
for (size_t j = 0; j < size; ++j)
{
m[i][j] = static_cast<double>(gen());
}
}
return m;
}
Contoh output berikut adalah untuk komputer yang memiliki empat prosesor.
serial: 3853
parallel: 1311
Mengompilasi Kode
Untuk mengkompilasi kode, salin lalu tempelkan dalam proyek Visual Studio, atau tempelkan dalam file yang diberi nama parallel-matrix-multiply.cpp
lalu jalankan perintah berikut di jendela Prompt Perintah Visual Studio.
cl.exe /EHsc parallel-matrix-multiply.cpp
Baca juga
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk