UPC (Unified Parallel C)
A parallel extension of ISO C99 built on the partitioned global address space model, designed for high-performance computing on large-scale shared and distributed memory machines.
Created by The UPC Consortium (government, industry, and academia)
Unified Parallel C (UPC) is a parallel programming language that extends ISO C99 with a small set of constructs for writing programs on large-scale parallel machines. It is built on the partitioned global address space (PGAS) model, in which every thread shares a single logical address space but each shared variable is physically associated with—and has affinity to—one particular thread. This design lets programmers read and write remote data with ordinary language syntax, as in shared-memory programming, while retaining explicit control over data layout and locality, as in message-passing programming. UPC targets the middle ground between the productivity of shared memory and the performance of distributed memory.
History & Origins
UPC did not emerge from a single designer or company. Instead, it was distilled from three earlier research efforts that each proposed parallel extensions to C: AC, developed at the Institute for Defense Analyses (IDA); Split-C, developed at the University of California, Berkeley; and the Parallel C Preprocessor (PCP), developed at Lawrence Livermore National Laboratory. UPC is not a strict superset of any of these; rather, its designers set out to combine the best characteristics of each into one coherent language.
The first formal definition, UPC Language Specification v1.0, was produced in February 2001 through the collaboration of a consortium spanning government, industry, and academia. Consortium participants included George Washington University, the Institute for Defense Analyses, the U.S. Department of Defense, UC Berkeley, Michigan Technological University, the University of Florida, Argonne National Laboratory, the Arctic Region Supercomputing Center, Hewlett-Packard, Cray, IBM, Intrepid Technology, Lawrence Berkeley National Laboratory, Lawrence Livermore National Laboratory, and the U.S. Department of Energy.
The specification evolved steadily over the following years. Version 1.1 arrived in May 2003, version 1.2 in May 2005, and version 1.3—reorganized into separate language and library documents—was released as a Lawrence Berkeley National Laboratory technical report in 2013.
Design Philosophy
UPC is designed around a single guiding idea: a programmer should be able to write parallel code that looks and reads much like sequential C, while still being able to reason precisely about where data lives and how much communication a given operation costs. Its core principles include:
- A single shared address space: Shared variables can be accessed directly by any thread, eliminating much of the boilerplate that message-passing libraries require.
- Locality awareness: Although the address space is shared, it is partitioned—each shared object has affinity to a specific thread, and the language exposes that affinity so programmers can minimize expensive remote accesses.
- SPMD execution: UPC follows a Single Program, Multiple Data model. A fixed number of threads is established at program startup, and each thread runs the same program over its own portion of the data.
- Familiarity: By building directly on ISO C99 rather than inventing new syntax wholesale, UPC lowers the barrier to entry for the large community of existing C programmers.
Key Features
The shared Type Qualifier
The central addition to C is the shared qualifier, which places a variable in the partitioned global address space rather than in a thread’s private memory:
| |
By default, elements of a shared array are distributed round-robin across threads, but a blocking factor can be specified to control how elements are grouped:
| |
THREADS and MYTHREAD
Two special values expose the SPMD execution model. THREADS is the total number of threads in the program, and MYTHREAD is the index of the currently executing thread:
| |
upc_forall
The upc_forall construct is a work-sharing loop that distributes iterations across threads according to an affinity expression, so that each thread executes the iterations whose data it owns:
| |
Synchronization and Memory Consistency
UPC provides barriers (upc_barrier, and the split-phase pair upc_notify / upc_wait), locks (upc_lock_t), and a memory consistency model that lets accesses be designated as strict (sequentially consistent) or relaxed (allowing reordering for performance). This gives programmers fine control over the trade-off between correctness guarantees and performance.
Bulk Communication and Memory Management
Beyond individual shared-variable accesses, UPC includes library routines for bulk data movement (upc_memput, upc_memget, upc_memcpy) and for collective dynamic allocation of shared memory (upc_all_alloc, upc_global_alloc, upc_alloc).
Implementations
UPC is a specification with several independent implementations rather than a single reference compiler:
- Berkeley UPC: An open-source, portable implementation from Lawrence Berkeley National Laboratory that translates UPC to C and relies on the GASNet communication library for network-independent, high-performance messaging. GASNet became influential in its own right, adopted by other PGAS languages and runtimes.
- GCC UPC (GNU UPC): An extension of the GNU Compiler Collection that adds native UPC support.
- Vendor compilers: Cray UPC, HP UPC, and IBM XL UPC provided implementations tuned to their respective supercomputer architectures.
According to Berkeley UPC project documentation, the implementation supports operating systems including Linux, macOS, and Cygwin, and networks including InfiniBand, TCP/IP Ethernet, and the HPE Slingshot interconnect through GASNet. The most recent Berkeley UPC release, version 2022.10.0, was published on October 28, 2022.
Evolution
UPC’s development was most active during the 2000s, when the language specification advanced from v1.0 through v1.2 and multiple vendor and open-source compilers reached maturity. The 2013 v1.3 specification, which cleanly separated the core language from its required and optional libraries, represents the most recent major revision of the standard.
In the years since, the center of gravity in the PGAS community at LBNL shifted toward UPC++, a C++ library that carries forward UPC’s partitioned global address space ideas—remote memory access, one-sided communication, and locality awareness—as a library rather than a language extension, with the first UPC++ v1.0 release published in September 2017. Berkeley UPC itself continues to receive maintenance releases that track new hardware, such as support for modern interconnects.
Current Relevance
UPC occupies a specialized but historically important niche in high-performance computing. It stands as one of the most prominent demonstrations of the PGAS model, alongside contemporaries such as Coarray Fortran, Titanium, Chapel, and X10. While mainstream HPC application development remains dominated by MPI (often combined with OpenMP), UPC’s approach influenced how the field thinks about global-address-space programming, and its GASNet communication layer remains a foundation for other PGAS runtimes.
The language is primarily encountered today in research computing, in academic parallel-programming courses, and in codebases originally written during the PGAS research wave of the 2000s. Its most direct living successor is UPC++, which brings the same conceptual model to modern C++.
Why It Matters
UPC matters because it made a serious, standardized attempt to give parallel programmers the best of two worlds: the readable, direct-access style of shared memory and the explicit locality control of message passing. By adding just a handful of well-chosen constructs to a language millions of programmers already knew, it lowered the conceptual cost of writing scalable parallel code. Even where UPC itself is no longer the tool of choice, the ideas it helped popularize—partitioned global address spaces, affinity-aware work sharing, and one-sided communication—continue to shape parallel programming languages and libraries today.
Timeline
Notable Uses & Legacy
Lawrence Berkeley National Laboratory
Developed and maintains the open-source Berkeley UPC compiler and the underlying GASNet communication layer, used for research computing across DOE facilities
U.S. Department of Defense / Department of Energy
Sponsored UPC's development through the consortium and applied it to scientific and defense HPC workloads on large parallel systems
George Washington University
A leading academic participant in the UPC Consortium; conducted foundational research, benchmarking, and teaching around the language
Cray, HP, and IBM
Shipped vendor UPC compilers (Cray UPC, HP UPC, IBM XL UPC) tuned for their supercomputer architectures
Computational science benchmarks
Used to implement PGAS versions of HPC kernels such as the NAS Parallel Benchmarks for evaluating scalability against MPI