Environment variables provide system-wide configuration for OpenMP programs without code modification. They control thread count, scheduling policies, processor binding, and other runtime behaviors. This enables performance tuning, testing, and deployment flexibility across different systems. Understanding these variables is essential for optimizing parallel applications and adapting to varying hardware configurations without recompilation.
Core Concept
OpenMP environment variables are set in the shell before program execution and affect all OpenMP directives unless overridden by code-level specifications. Key variables include OMP_NUM_THREADS (thread count), OMP_SCHEDULE (loop scheduling policy), OMP_PROC_BIND (thread affinity), and others controlling nested parallelism, stack size, and dynamic adjustment.
Key Points
- OMP_NUM_THREADS: Sets default thread count (e.g.,
export OMP_NUM_THREADS=4) - OMP_SCHEDULE: Default scheduling for loops (e.g.,
dynamic,10) - OMP_PROC_BIND: Thread-to-processor binding (true, false, master, close, spread)
- OMP_NESTED: Enables nested parallelism (deprecated in OpenMP 5.0)
- OMP_STACKSIZE: Thread stack size (e.g.,
8M,1G) - OMP_WAIT_POLICY: Thread waiting behavior (active or passive)
Code Example
Program demonstrating environment variable effects on execution
OpenMP Implementation:
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
int main() {
// Display current environment variable settings
printf("Environment Variable Settings:\n");
printf(" OMP_NUM_THREADS = %s\n", getenv("OMP_NUM_THREADS") ? getenv("OMP_NUM_THREADS") : "not set");
printf(" OMP_SCHEDULE = %s\n", getenv("OMP_SCHEDULE") ? getenv("OMP_SCHEDULE") : "not set");
printf(" OMP_PROC_BIND = %s\n\n", getenv("OMP_PROC_BIND") ? getenv("OMP_PROC_BIND") : "not set");
// Show actual runtime configuration
printf("Runtime Configuration:\n");
printf(" Max threads: %d\n", omp_get_max_threads());
printf(" Nested parallelism: %d\n", omp_get_nested());
printf(" Dynamic adjustment: %d\n\n", omp_get_dynamic());
// Parallel region using environment settings
#pragma omp parallel
{
#pragma omp master
{
printf("Parallel Execution:\n");
printf(" Active threads: %d\n", omp_get_num_threads());
}
}
// Loop with schedule affected by OMP_SCHEDULE
printf("\nParallel loop execution:\n");
#pragma omp parallel for schedule(runtime)
for (int i = 0; i < 8; i++) {
printf(" Iteration %d on thread %d\n", i, omp_get_thread_num());
}
return 0;
}
Running with Environment Variables:
export OMP_NUM_THREADS=4
export OMP_SCHEDULE="dynamic,2"
./env_vars_demo
Usage & Best Practices
When to Use
- Deploying applications across different systems
- Performance tuning without recompilation
- Testing scalability with various configurations
- Batch job submission with specific requirements
Best Practices
- Set
OMP_NUM_THREADSto match available cores - Use
OMP_SCHEDULE="dynamic"for load-balanced irregular workloads - Enable
OMP_PROC_BIND=truefor NUMA systems - Document required environment settings in README
- Provide sensible defaults in code as fallback
Common Mistakes
- Forgetting to export variables (use
export) - Setting conflicting values in script vs environment
Key Takeaways
Summary:
- Environment variables configure OpenMP runtime without code changes
OMP_NUM_THREADScontrols default thread countOMP_SCHEDULEsets loop scheduling policy forschedule(runtime)OMP_PROC_BINDmanages thread affinity- Code-level specifications override environment variables
Quick Reference
Essential Environment Variables:
export OMP_NUM_THREADS=8 # Thread count
export OMP_SCHEDULE="dynamic,10" # Loop scheduling
export OMP_PROC_BIND=true # Thread binding
export OMP_STACKSIZE=8M # Thread stack size
export OMP_WAIT_POLICY=passive # Waiting policy
export OMP_DISPLAY_ENV=true # Show settings at startup
Query in Shell:
echo $OMP_NUM_THREADS
env | grep OMP_