Skip to content

Commit 001a1f2

Browse files
committed
Merge branch 'main' of github.com:Insper/supercomp
2 parents 9870a19 + 2de9185 commit 001a1f2

File tree

1 file changed

+81
-43
lines changed

1 file changed

+81
-43
lines changed

material/aulas/aula03/index.md

Lines changed: 81 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ Analise o código `matmul_seq.cpp`:
3535
#include <cstdlib>
3636
#include <algorithm>
3737

38+
39+
#define TAM_MATRIZ 1000
3840
/*
3941
============================================================
4042
OBJETIVO
@@ -53,71 +55,107 @@ Analise o código `matmul_seq.cpp`:
5355
5456
============================================================
5557
*/
56-
int main(int argc, char* argv[]) {
57-
const int N = 2000; // Tamanho da matriz
58-
int B = 0; // Tamanho do bloco. Se for 0 → versão ingênua.
5958

60-
// Lê o tamanho do bloco da linha de comando
61-
// Exemplo: ./matmul_seq 200 → roda com blocos 200×200
62-
if (argc > 1) {
63-
// Atualiza o valor de B de acordo com o parâmetro de entrada
64-
B = std::atoi(argv[1]);
65-
}
59+
/* Definicoes para melhorar a legibilidade*/
60+
61+
using Matriz = std::vector<std::vector<double>>;
62+
63+
inline Matriz criaMatriz(int size, double value){
64+
return Matriz(size, std::vector<double>(size, value));
65+
}
66+
67+
/**
68+
* @brief Versão ingênua da multiplicação de matrizes.
69+
*
70+
* Implementa a multiplicação com três loops aninhados (i, j, k) sem uso de tiling.
71+
* O acesso às matrizes é feito de forma direta, sem otimizações de cache.
72+
*/
73+
inline void versaoIngenua(){
6674

6775
// Cria três matrizes NxN em memória, preenchidas com valores fixos
6876
// - A inicializada com 1.0
6977
// - Bmat inicializada com 2.0
7078
// - C inicializada com 0.0 (resultado)
71-
std::vector<std::vector<double>> A(N, std::vector<double>(N, 1.0));
72-
std::vector<std::vector<double>> Bmat(N, std::vector<double>(N, 2.0));
73-
std::vector<std::vector<double>> C(N, std::vector<double>(N, 0.0));
7479

75-
// Marca o início da medição de tempo
76-
auto start = std::chrono::high_resolution_clock::now();
80+
Matriz A = criaMatriz(TAM_MATRIZ, 1.0);
81+
Matriz Bmat = criaMatriz(TAM_MATRIZ, 2.0);
82+
Matriz C = criaMatriz(TAM_MATRIZ, 0.0);
7783

78-
if (B <= 0) {
79-
// ========================================================
80-
// VERSÃO INGENUA
81-
// --------------------------------------------------------
82-
// Três loops aninhados (i, j, k)
83-
// Acesso às matrizes sem tiling
84-
// ========================================================
85-
for (int i = 0; i < N; i++) {
86-
for (int j = 0; j < N; j++) {
87-
for (int k = 0; k < N; k++) {
88-
C[i][j] += A[i][k] * Bmat[k][j];
89-
}
84+
for (int i = 0; i < TAM_MATRIZ; i++) {
85+
for (int j = 0; j < TAM_MATRIZ; j++) {
86+
for (int k = 0; k < TAM_MATRIZ; k++) {
87+
C[i][j] += A[i][k] * Bmat[k][j];
9088
}
9189
}
92-
} else {
93-
// ========================================================
94-
// VERSÃO COM TILING
95-
// ========================================================
96-
for (int ii = 0; ii < N; ii += B) { // blocos de linhas
97-
for (int jj = 0; jj < N; jj += B) { // blocos de colunas
98-
for (int kk = 0; kk < N; kk += B) { // blocos intermediários
99-
// Multiplicação de submatrizes B×B
100-
// Ordem j -> i -> k
101-
for (int j = jj; j < std::min(jj + B, N); j++) {
102-
for (int i = ii; i < std::min(ii + B, N); i++) {
103-
double sum = C[i][j];
104-
for (int k = kk; k < std::min(kk + B, N); k++) {
105-
sum += A[i][k] * Bmat[k][j];
106-
}
107-
C[i][j] = sum;
90+
}
91+
}
92+
93+
/**
94+
* @brief Multiplicação de matrizes utilizando a técnica de tiling (blocking).
95+
*
96+
* Realiza a multiplicação de matrizes dividindo as matrizes em blocos (tiles) de tamanho `tamBloco`.
97+
* Otimiza o uso da cache ao trabalhar com submatrizes menores que cabem na hierarquia de memória.
98+
*
99+
* @param tamBloco Tamanho do bloco (tile) usado para dividir as matrizes na multiplicação.
100+
*/
101+
inline void versaoTiling(int tamBloco){
102+
103+
// Cria três matrizes NxN em memória, preenchidas com valores fixos
104+
// - A inicializada com 1.0
105+
// - Bmat inicializada com 2.0
106+
// - C inicializada com 0.0 (resultado)
107+
108+
Matriz A = criaMatriz(TAM_MATRIZ, 1.0);
109+
Matriz Bmat = criaMatriz(TAM_MATRIZ, 2.0);
110+
Matriz C = criaMatriz(TAM_MATRIZ, 0.0);
111+
112+
for (int ii = 0; ii < TAM_MATRIZ; ii += tamBloco) { // blocos de linhas
113+
for (int jj = 0; jj < TAM_MATRIZ; jj += tamBloco) { // blocos de colunas
114+
for (int kk = 0; kk < TAM_MATRIZ; kk += tamBloco) {// blocos intermediários
115+
// Multiplicação de submatrizes tamBloco x tamBloco
116+
// Ordem j -> i -> k
117+
for (int j = jj; j < std::min(jj + tamBloco, TAM_MATRIZ); j++) {
118+
for (int i = ii; i < std::min(ii + tamBloco, TAM_MATRIZ); i++) {
119+
double sum = C[i][j];
120+
for (int k = kk; k < std::min(kk + tamBloco, TAM_MATRIZ); k++) {
121+
sum += A[i][k] * Bmat[k][j];
108122
}
123+
C[i][j] = sum;
109124
}
110125
}
111126
}
112127
}
113128
}
129+
}
130+
131+
132+
133+
int main(int argc, char* argv[]) {
134+
int tamBloco = 0; // Tamanho do bloco. Se for 0 → versão ingênua.
135+
136+
// Lê o tamanho do bloco da linha de comando
137+
// Exemplo: ./matmul_seq 200 → roda com blocos 200×200
138+
if (argc > 1) {
139+
// Atualiza o valor de tamBloco de acordo com o parâmetro de entrada
140+
tamBloco = std::atoi(argv[1]);
141+
}
142+
143+
// Marca o início da medição de tempo
144+
auto start = std::chrono::high_resolution_clock::now();
145+
146+
if (tamBloco <= 0) {
147+
versaoIngenua();
148+
}
149+
else {
150+
versaoTiling(tamBloco);
151+
}
114152

115153
// Marca o fim da medição
116154
auto end = std::chrono::high_resolution_clock::now();
117155

118156
// Calcula e imprime o tempo total em milissegundos
119157
std::cout << "Execução ("
120-
<< (B <= 0 ? "ingênua" : "tiling B=" + std::to_string(B))
158+
<< (tamBloco <= 0 ? "ingênua" : "tiling tamBloco=" + std::to_string(tamBloco))
121159
<< "): "
122160
<< std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count()
123161
<< " ms" << std::endl;

0 commit comments

Comments
 (0)