💻 Exemplos: Capítulo 18: Programação de Baixo Nível: Bitwise, Cache Lines e Alinhamento
💻 Exemplos: Capítulo 18: Programação de Baixo Nível: Bitwise, Cache Lines e Alinhamento
Especialização em Sistemas com C++ • Demonstrações Práticas Compiláveis
🎯 Objetivo dos Exemplos
Apresentar as otimizações de microarquitetura essenciais em sistemas de tempo real: operações bit a bit (bitwise manipulation) para flags compactas de hardware, o uso de alignas(64) para isolar variáveis em linhas de cache L1/L2 distintas e eliminar a degradação de performance por Falso Compartilhamento (False Sharing) em sistemas multiprocessados.
1. Código Fonte Completo (main.cpp)
/**
* @file main.cpp
* @brief Otimizações de baixo nível: bitwise masks e prevenção de false sharing com alignas em C++20.
*/
#include <iostream>
#include <cstdint>
#include <thread>
#include <vector>
#include <new> // std::hardware_destructive_interference_size
// 1. Bitwise Flags para Registrador de Hardware
namespace FlagsHardware {
constexpr std::uint8_t SENSOR_HABILITADO = 1 << 0; // 0000 0001 (0x01)
constexpr std::uint8_t INTERRUPCAO_ATIVA = 1 << 1; // 0000 0010 (0x02)
constexpr std::uint8_t MODO_ALTA_PRECISAO = 1 << 2; // 0000 0100 (0x04)
constexpr std::uint8_t FALHA_SINAL_PARIDADE = 1 << 3; // 0000 1000 (0x08)
}
// 2. Estrutura Sujeita a Falso Compartilhamento (False Sharing)
struct ContadoresFalseSharing {
uint64_t worker_1{0}; // Mesma cache line de 64 bytes
uint64_t worker_2{0}; // Linha invalidada a cada escrita concorrente!
};
// 3. Estrutura Otimizada com Alinhamento Explicito de Cache Line (64 Bytes)
struct ContadoresAlinhados {
alignas(64) uint64_t worker_1{0}; // Isolado em sua própria cache line
alignas(64) uint64_t worker_2{0}; // Zero contenção de barramento de cache!
};
int main() {
std::cout << "=== CAPÍTULO 18: BAIXO NÍVEL, BITWISE E CACHE LINES ===" << '\n';
// 4. Manipulação de Flags Bitwise
std::uint8_t registrador = 0;
// Ativa SENSOR_HABILITADO e MODO_ALTA_PRECISAO (OR)
registrador |= (FlagsHardware::SENSOR_HABILITADO | FlagsHardware::MODO_ALTA_PRECISAO);
std::cout << "Registrador apos ligar bits (0x01 | 0x04): 0x"
<< std::hex << static_cast<int>(registrador) << std::dec << '\n';
// Testa se INTERRUPCAO_ATIVA está ligada (AND)
bool isr_on = (registrador & FlagsHardware::INTERRUPCAO_ATIVA) != 0;
std::cout << "Interrupcao esta ativa? " << (isr_on ? "SIM" : "NAO") << '\n';
// Limpa MODO_ALTA_PRECISAO (AND com NOT)
registrador &= ~FlagsHardware::MODO_ALTA_PRECISAO;
std::cout << "Registrador apos desligar alta precisao: 0x"
<< std::hex << static_cast<int>(registrador) << std::dec << '\n';
// Inverte estado do sensor (XOR)
registrador ^= FlagsHardware::SENSOR_HABILITADO;
std::cout << "Registrador apos toggle do sensor (XOR): 0x"
<< std::hex << static_cast<int>(registrador) << std::dec << '\n';
// 5. Análise de Alinhamento de Memória e False Sharing
std::cout << "\n--- Inspeção de Cache Line e Estruturas ---" << '\n';
std::cout << "Tamanho de ContadoresFalseSharing: " << sizeof(ContadoresFalseSharing) << " bytes." << '\n';
std::cout << "Tamanho de ContadoresAlinhados: " << sizeof(ContadoresAlinhados) << " bytes." << '\n';
std::cout << "Alinhamento de ContadoresAlinhados: " << alignof(ContadoresAlinhados) << " bytes." << '\n';
ContadoresAlinhados pool;
std::cout << "Endereco worker_1: " << static_cast<void*>(&pool.worker_1) << '\n';
std::cout << "Endereco worker_2: " << static_cast<void*>(&pool.worker_2) << '\n';
auto delta_enderecos = reinterpret_cast<uintptr_t>(&pool.worker_2) - reinterpret_cast<uintptr_t>(&pool.worker_1);
std::cout << "Distancia fisica entre workers: " << delta_enderecos << " bytes (Cache Line Boundary Protegida!)" << '\n';
return 0;
}
2. Instruções de Compilação e Execução
# Compilação com GCC / Clang
g++ -std=c++20 -Wall -Wextra -O2 main.cpp -o app_baixo_nivel
./app_baixo_nivel
# Compilação com MSVC
cl /std:c++20 /EHsc /W4 /O2 main.cpp /Fe:app_baixo_nivel.exe
.\app_baixo_nivel.exe
3. Saída Esperada no Terminal
=== CAPÍTULO 18: BAIXO NÍVEL, BITWISE E CACHE LINES ===
Registrador apos ligar bits (0x01 | 0x04): 0x5
Interrupcao esta ativa? NAO
Registrador apos desligar alta precisao: 0x1
Registrador apos toggle do sensor (XOR): 0x0
--- Inspeção de Cache Line e Estruturas ---
Tamanho de ContadoresFalseSharing: 16 bytes.
Tamanho de ContadoresAlinhados: 128 bytes.
Alinhamento de ContadoresAlinhados: 64 bytes.
Endereco worker_1: 0x7ffd9b80a080
Endereco worker_2: 0x7ffd9b80a0c0
Distancia fisica entre workers: 64 bytes (Cache Line Boundary Protegida!)