hpc-patterns
High-performance computing patterns for C++20 including cache-friendly data structures, SIMD vectorization, memory management, thread parallelism, lock-free data structures, and NUMA-aware allocation.
What this skill does
# HPC Patterns for C++20
Domain knowledge for building high-performance computing applications with optimal hardware utilization.
## Cache-Friendly Data Structures
### Structure of Arrays (SoA) vs Array of Structures (AoS)
```cpp
// BAD: Array of Structures (poor cache utilization for position-only access)
struct ParticleAoS {
double x, y, z; // position
double vx, vy, vz; // velocity
double fx, fy, fz; // force
double mass;
int type;
bool active;
};
std::vector<ParticleAoS> particles(N); // Stride = sizeof(ParticleAoS)
// GOOD: Structure of Arrays (contiguous access per field)
struct ParticlesSoA {
std::vector<double> x, y, z;
std::vector<double> vx, vy, vz;
std::vector<double> fx, fy, fz;
std::vector<double> mass;
std::vector<int> type;
std::vector<bool> active;
explicit ParticlesSoA(size_t n)
: x(n), y(n), z(n), vx(n), vy(n), vz(n),
fx(n), fy(n), fz(n), mass(n), type(n), active(n) {}
};
```
### Cache Line Alignment
```cpp
// Align to cache line boundaries
struct alignas(64) CacheAlignedBlock {
std::array<double, 8> data; // 64 bytes = 1 cache line
};
// Padding to avoid false sharing in multithreaded code
struct alignas(64) ThreadLocalCounter {
std::atomic<int64_t> count{0};
char padding[64 - sizeof(std::atomic<int64_t>)]; // Fill cache line
};
```
### Tiling for Cache Reuse
```cpp
// Cache-oblivious matrix multiply (blocked)
void MatMulBlocked(std::span<const double> A, std::span<const double> B,
std::span<double> C, int N, int block_size = 64) {
for (int ii = 0; ii < N; ii += block_size) {
for (int jj = 0; jj < N; jj += block_size) {
for (int kk = 0; kk < N; kk += block_size) {
int i_end = std::min(ii + block_size, N);
int j_end = std::min(jj + block_size, N);
int k_end = std::min(kk + block_size, N);
for (int i = ii; i < i_end; ++i) {
for (int k = kk; k < k_end; ++k) {
double a_ik = A[i * N + k];
for (int j = jj; j < j_end; ++j) {
C[i * N + j] += a_ik * B[k * N + j];
}
}
}
}
}
}
}
```
## SIMD Vectorization
### Compiler Auto-Vectorization Hints
```cpp
// Restrict pointers for no-alias guarantee
void VectorAdd(double* __restrict__ out,
const double* __restrict__ a,
const double* __restrict__ b, size_t n) {
#pragma omp simd
for (size_t i = 0; i < n; ++i) {
out[i] = a[i] + b[i];
}
}
// Aligned access for vectorization
void ScaleVector(double* __restrict__ data, double factor, size_t n) {
assert(reinterpret_cast<uintptr_t>(data) % 32 == 0); // AVX alignment
#pragma omp simd aligned(data: 32)
for (size_t i = 0; i < n; ++i) {
data[i] *= factor;
}
}
```
### Explicit SIMD with Intrinsics (when needed)
```cpp
#include <immintrin.h>
// AVX2 dot product
double DotProductAVX(const double* a, const double* b, size_t n) {
__m256d sum = _mm256_setzero_pd();
size_t i = 0;
for (; i + 4 <= n; i += 4) {
__m256d va = _mm256_load_pd(a + i);
__m256d vb = _mm256_load_pd(b + i);
sum = _mm256_fmadd_pd(va, vb, sum);
}
// Horizontal sum
double result[4];
_mm256_store_pd(result, sum);
double total = result[0] + result[1] + result[2] + result[3];
// Remainder
for (; i < n; ++i) total += a[i] * b[i];
return total;
}
```
## Memory Management
### Custom Allocator for Aligned Memory
```cpp
template <typename T, size_t Alignment = 64>
class AlignedAllocator {
public:
using value_type = T;
T* allocate(size_t n) {
void* ptr = std::aligned_alloc(Alignment, n * sizeof(T));
if (!ptr) throw std::bad_alloc();
return static_cast<T*>(ptr);
}
void deallocate(T* ptr, size_t) noexcept {
std::free(ptr);
}
};
// Usage
using AlignedVector = std::vector<double, AlignedAllocator<double, 64>>;
AlignedVector data(1024); // 64-byte aligned for AVX-512
```
### Memory Pool for Fixed-Size Allocations
```cpp
template <typename T, size_t PoolSize = 4096>
class MemoryPool {
public:
T* Allocate() {
if (free_list_) {
T* ptr = free_list_;
free_list_ = *reinterpret_cast<T**>(ptr);
return ptr;
}
if (next_ >= PoolSize) throw std::bad_alloc();
return &pool_[next_++];
}
void Deallocate(T* ptr) noexcept {
*reinterpret_cast<T**>(ptr) = free_list_;
free_list_ = ptr;
}
private:
std::array<T, PoolSize> pool_;
T* free_list_ = nullptr;
size_t next_ = 0;
};
```
## Thread Parallelism
### Thread Pool with Work Stealing
```cpp
#include <thread>
#include <future>
#include <queue>
class ThreadPool {
public:
explicit ThreadPool(size_t num_threads = std::thread::hardware_concurrency()) {
for (size_t i = 0; i < num_threads; ++i) {
workers_.emplace_back([this] { WorkerLoop(); });
}
}
~ThreadPool() {
{
std::lock_guard lock(mutex_);
stop_ = true;
}
cv_.notify_all();
for (auto& w : workers_) w.join();
}
template <typename F, typename... Args>
auto Submit(F&& f, Args&&... args) -> std::future<std::invoke_result_t<F, Args...>> {
using ReturnType = std::invoke_result_t<F, Args...>;
auto task = std::make_shared<std::packaged_task<ReturnType()>>(
std::bind(std::forward<F>(f), std::forward<Args>(args)...));
auto future = task->get_future();
{
std::lock_guard lock(mutex_);
tasks_.emplace([task] { (*task)(); });
}
cv_.notify_one();
return future;
}
private:
void WorkerLoop() {
while (true) {
std::function<void()> task;
{
std::unique_lock lock(mutex_);
cv_.wait(lock, [this] { return stop_ || !tasks_.empty(); });
if (stop_ && tasks_.empty()) return;
task = std::move(tasks_.front());
tasks_.pop();
}
task();
}
}
std::vector<std::jthread> workers_;
std::queue<std::function<void()>> tasks_;
std::mutex mutex_;
std::condition_variable cv_;
bool stop_ = false;
};
```
### Parallel For with Chunking
```cpp
template <typename Func>
void ParallelFor(size_t begin, size_t end, Func&& func,
size_t chunk_size = 0) {
size_t n = end - begin;
size_t num_threads = std::thread::hardware_concurrency();
if (chunk_size == 0) chunk_size = std::max(size_t{1}, n / num_threads);
std::vector<std::jthread> threads;
for (size_t start = begin; start < end; start += chunk_size) {
size_t stop = std::min(start + chunk_size, end);
threads.emplace_back([&func, start, stop] {
for (size_t i = start; i < stop; ++i) {
func(i);
}
});
}
// jthreads auto-join on destruction
}
// Usage
ParallelFor(0, N, [&](size_t i) {
result[i] = ComputeExpensive(data[i]);
});
```
## Lock-Free Data Structures
### Lock-Free Stack (Treiber Stack)
```cpp
template <typename T>
class LockFreeStack {
struct Node {
T data;
Node* next;
};
public:
void Push(T value) {
auto* node = new Node{std::move(value), nullptr};
node->next = head_.load(std::memory_order_relaxed);
while (!head_.compare_exchange_weak(node->next, node,
std::memory_order_release, std::memory_order_relaxed)) {}
}
std::optional<T> Pop() {
Node* old_head = head_.load(std::memory_order_relaxed);
while (old_head &&
!head_.compare_exchange_weak(old_head, old_head->next,
std::memory_order_acquire, std::memory_order_relaxed)) {}
if (!old_head) return std::nullopt;
T value = std::move(old_head->data);
delete old_head; // Note: real impl needs hazard pointers or epoch GC
return value;
}
private:
std::atomic<Node*> head_{nullptr};
};
```
## NUMA-Aware Allocation
### First-Touch Policy
```cpp
// Initialize data on the NUMA node where it will be accessed
void InitializeParallel(std::span<double> data, size_t num_threads) {
size_t chunk = data.size() / num_threads;
std::vector<std::jthread> threads;
for (size_t t = 0; t < num_threads; ++t) {
size_t start = t * cRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.