0% found this document useful (0 votes)
6 views

Programming Persistent Memory Steve Scargall download

The document is a comprehensive guide titled 'Programming Persistent Memory' by Steve Scargall, focusing on the principles and practices of persistent memory programming for developers. It covers various aspects such as architecture, operating system support, fundamental concepts, and the Persistent Memory Development Kit. The book is available for download and is licensed under the Creative Commons Attribution 4.0 International License.

Uploaded by

mitzadrisya
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

Programming Persistent Memory Steve Scargall download

The document is a comprehensive guide titled 'Programming Persistent Memory' by Steve Scargall, focusing on the principles and practices of persistent memory programming for developers. It covers various aspects such as architecture, operating system support, fundamental concepts, and the Persistent Memory Development Kit. The book is available for download and is licensed under the Creative Commons Attribution 4.0 International License.

Uploaded by

mitzadrisya
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 86

Programming Persistent Memory Steve Scargall

download

https://ebookbell.com/product/programming-persistent-memory-
steve-scargall-59042598

Explore and download more ebooks at ebookbell.com


Here are some recommended products that we believe you will be
interested in. You can click the link to download.

Programming Persistent Memory A Comprehensive Guide For Developers 1st


Edition Steve Scargall

https://ebookbell.com/product/programming-persistent-memory-a-
comprehensive-guide-for-developers-1st-edition-steve-scargall-34689828

Vertically Integrated Architectures Versioned Data Models Implicit


Services And Persistenceaware Programming 1st Edition Jos Jong

https://ebookbell.com/product/vertically-integrated-architectures-
versioned-data-models-implicit-services-and-persistenceaware-
programming-1st-edition-jos-jong-7293810

Programming Languages And Systems 31st European Symposium On


Programming Esop 2022 Held As Part Of The European Joint Conferences
On Theory And Practice Of Software Etaps 2022 Munich Germany April 27
2022 Proceedings Ilya Sergey
https://ebookbell.com/product/programming-languages-and-systems-31st-
european-symposium-on-programming-esop-2022-held-as-part-of-the-
european-joint-conferences-on-theory-and-practice-of-software-
etaps-2022-munich-germany-april-27-2022-proceedings-ilya-
sergey-44887738

Programming 101 Learn To Code Using The Processing Programming


Language 2nd Edition 2nd Jeanine Meyer

https://ebookbell.com/product/programming-101-learn-to-code-using-the-
processing-programming-language-2nd-edition-2nd-jeanine-meyer-46238180
Programming 101 The How And Why Of Programming Revealed Using The
Processing Programming Language Jeanine Meyer

https://ebookbell.com/product/programming-101-the-how-and-why-of-
programming-revealed-using-the-processing-programming-language-
jeanine-meyer-46318424

Programming And Gui Fundamentals Tcltk For Electronic Design


Automation Suman Lata Tripathi

https://ebookbell.com/product/programming-and-gui-fundamentals-tcltk-
for-electronic-design-automation-suman-lata-tripathi-46318712

Programming With Openscad A Beginners Guide To Coding 3dprintable


Objects 1st Edition Justin Gohde

https://ebookbell.com/product/programming-with-openscad-a-beginners-
guide-to-coding-3dprintable-objects-1st-edition-justin-gohde-46410140

Programming In Two Semesters Using Python And Java Quentin Charatan

https://ebookbell.com/product/programming-in-two-semesters-using-
python-and-java-quentin-charatan-46494972

Programming The Future Politics Resistance And Utopia In Contemporary


Speculative Tv Sherryl Vint Jonathan Alexander

https://ebookbell.com/product/programming-the-future-politics-
resistance-and-utopia-in-contemporary-speculative-tv-sherryl-vint-
jonathan-alexander-46771488
Programming
Persistent
Memory
A Comprehensive Guide for Developers

Steve Scargall
Programming Persistent
Memory
A Comprehensive Guide for
Developers

Steve Scargall
Programming Persistent Memory: A Comprehensive Guide for Developers

Steve Scargall
Santa Clara, CA, USA

ISBN-13 (pbk): 978-1-4842-4931-4 ISBN-13 (electronic): 978-1-4842-4932-1


https://doi.org/10.1007/978-1-4842-4932-1
Copyright © 2020 by Intel
This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the material is
concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation, broadcasting, reproduction
on microfilms or in any other physical way, and transmission or information storage and retrieval, electronic
adaptation, computer software, or by similar or dissimilar methodology now known or hereafter developed.
Open Access This book is licensed under the terms of the Creative Commons Attribution 4.0
International License (http://creativecommons.org/licenses/by/4.0/), which permits use,
sharing, adaptation, distribution and reproduction in any medium or format, as long as you give
appropriate credit to the original author(s) and the source, provide a link to the Creative Commons license and
indicate if changes were made.
The images or other third party material in this book are included in the book’s Creative Commons license, unless
indicated otherwise in a credit line to the material. If material is not included in the book’s Creative Commons
license and your intended use is not permitted by statutory regulation or exceeds the permitted use, you will need
to obtain permission directly from the copyright holder.
Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with every
occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an editorial fashion
and to the benefit of the trademark owner, with no intention of infringement of the trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not identified
as such, is not to be taken as an expression of opinion as to whether or not they are subject to proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of publication, neither
the authors nor the editors nor the publisher can accept any legal responsibility for any errors or omissions that may
be made. The publisher makes no warranty, express or implied, with respect to the material contained herein.
Managing Director, Apress Media LLC: Welmoed Spahr
Acquisitions Editor: Susan McDermott
Development Editor: Laura Berendson
Coordinating Editor: Jessica Vakili
Distributed to the book trade worldwide by Springer Science+Business Media New York, 233 Spring Street,
6th Floor, New York, NY 10013. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail orders-ny@springer-sbm.com,
or visit www.springeronline.com. Apress Media, LLC is a California LLC and the sole member (owner) is Springer
Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc is a Delaware corporation.
For information on translations, please e-mail rights@apress.com, or visit http://www.apress.com/
rights-permissions.
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and licenses
are also available for most titles. For more information, reference our Print and eBook Bulk Sales web page at
http://www.apress.com/bulk-sales.
Any source code or other supplementary material referenced by the author in this book is available to readers on
GitHub via the book's product page, located at www.apress.com/978-1-4842-4931-4. For more detailed
information, please visit http://www.apress.com/source-code.
Printed on acid-free paper
Table of Contents
About the Author��������������������������������������������������������������������������������������������������� xiii
About the Technical Reviewer���������������������������������������������������������������������������������xv
About the Contributors������������������������������������������������������������������������������������������xvii
Acknowledgments��������������������������������������������������������������������������������������������������xxi
Preface�����������������������������������������������������������������������������������������������������������������xxiii

Chapter 1: Introduction to Persistent Memory Programming���������������������������������� 1


A High-Level Example Program���������������������������������������������������������������������������������������������������� 2
What’s Different?��������������������������������������������������������������������������������������������������������������������� 5
The Performance Difference��������������������������������������������������������������������������������������������������� 6
Program Complexity���������������������������������������������������������������������������������������������������������������� 7
How Does libpmemkv Work?��������������������������������������������������������������������������������������������������� 8
What’s Next?��������������������������������������������������������������������������������������������������������������������������������� 9
Summary�������������������������������������������������������������������������������������������������������������������������������������� 9

Chapter 2: Persistent Memory Architecture����������������������������������������������������������� 11


Persistent Memory Characteristics��������������������������������������������������������������������������������������������� 12
Platform Support for Persistent Memory������������������������������������������������������������������������������������ 13
Cache Hierarchy�������������������������������������������������������������������������������������������������������������������������� 14
Power-Fail Protected Domains���������������������������������������������������������������������������������������������������� 16
The Need for Flushing, Ordering, and Fencing���������������������������������������������������������������������������� 19
Data Visibility������������������������������������������������������������������������������������������������������������������������������ 23
Intel Machine Instructions for Persistent Memory���������������������������������������������������������������������� 24
Detecting Platform Capabilities�������������������������������������������������������������������������������������������������� 25

iii
Table of Contents

Application Startup and Recovery����������������������������������������������������������������������������������������������� 27


What’s Next?������������������������������������������������������������������������������������������������������������������������������� 29
Summary������������������������������������������������������������������������������������������������������������������������������������ 29

Chapter 3: Operating System Support for Persistent Memory������������������������������� 31


Operating System Support for Memory and Storage������������������������������������������������������������������ 31
Persistent Memory As Block Storage������������������������������������������������������������������������������������������ 33
Persistent Memory-Aware File Systems������������������������������������������������������������������������������������� 34
Memory-Mapped Files���������������������������������������������������������������������������������������������������������������� 35
Persistent Memory Direct Access (DAX)������������������������������������������������������������������������������������� 43
Summary������������������������������������������������������������������������������������������������������������������������������������ 53

Chapter 4: Fundamental Concepts of Persistent Memory Programming��������������� 55


What’s Different?������������������������������������������������������������������������������������������������������������������������ 55
Atomic Updates��������������������������������������������������������������������������������������������������������������������������� 56
Transactions�������������������������������������������������������������������������������������������������������������������������������� 57
Atomicity������������������������������������������������������������������������������������������������������������������������������� 57
Consistency��������������������������������������������������������������������������������������������������������������������������� 58
Isolation��������������������������������������������������������������������������������������������������������������������������������� 58
Durability������������������������������������������������������������������������������������������������������������������������������� 58
Flushing Is Not Transactional������������������������������������������������������������������������������������������������������ 59
Start-Time Responsibilities��������������������������������������������������������������������������������������������������������� 59
Tuning for Hardware Configurations������������������������������������������������������������������������������������������� 60
Summary������������������������������������������������������������������������������������������������������������������������������������ 60

Chapter 5: Introducing the Persistent Memory Development Kit��������������������������� 63


Background��������������������������������������������������������������������������������������������������������������������������������� 63
Choosing the Right Semantics���������������������������������������������������������������������������������������������������� 64
Volatile Libraries������������������������������������������������������������������������������������������������������������������������� 65
libmemkind���������������������������������������������������������������������������������������������������������������������������� 65
libvmemcache����������������������������������������������������������������������������������������������������������������������� 66
libvmem��������������������������������������������������������������������������������������������������������������������������������� 67

iv
Table of Contents

Persistent Libraries��������������������������������������������������������������������������������������������������������������������� 67
libpmem�������������������������������������������������������������������������������������������������������������������������������� 67
libpmemobj���������������������������������������������������������������������������������������������������������������������������� 68
libpmemobj-cpp�������������������������������������������������������������������������������������������������������������������� 68
libpmemkv����������������������������������������������������������������������������������������������������������������������������� 69
libpmemlog���������������������������������������������������������������������������������������������������������������������������� 69
libpmemblk���������������������������������������������������������������������������������������������������������������������������� 69
Tools and Command Utilities������������������������������������������������������������������������������������������������������� 70
pmempool������������������������������������������������������������������������������������������������������������������������������ 70
pmemcheck��������������������������������������������������������������������������������������������������������������������������� 70
pmreorder������������������������������������������������������������������������������������������������������������������������������ 71
Summary������������������������������������������������������������������������������������������������������������������������������������ 71

Chapter 6: libpmem: Low-Level Persistent Memory Support��������������������������������� 73


Using the Library������������������������������������������������������������������������������������������������������������������������� 74
Mapping a File���������������������������������������������������������������������������������������������������������������������������� 75
Copying to Persistent Memory���������������������������������������������������������������������������������������������������� 76
Separating the Flush Steps��������������������������������������������������������������������������������������������������������� 77
Summary������������������������������������������������������������������������������������������������������������������������������������ 79

Chapter 7: libpmemobj: A Native Transactional Object Store��������������������������������� 81


What is libpmemobj?������������������������������������������������������������������������������������������������������������������ 81
Why not malloc( )?����������������������������������������������������������������������������������������������������������������������� 82
Grouping Operations������������������������������������������������������������������������������������������������������������������� 83
Memory Pools����������������������������������������������������������������������������������������������������������������������������� 83
Creating Memory Pools��������������������������������������������������������������������������������������������������������� 83
Pool Object Pointer (POP) and the Root Object���������������������������������������������������������������������� 87
Opening and Reading from Memory Pools���������������������������������������������������������������������������� 88
Memory Poolsets������������������������������������������������������������������������������������������������������������������������ 90
Concatenated Poolsets���������������������������������������������������������������������������������������������������������� 90
Replica Poolsets�������������������������������������������������������������������������������������������������������������������� 91
Managing Memory Pools and Poolsets��������������������������������������������������������������������������������������� 92

v
Table of Contents

Typed Object Identifiers (TOIDs)�������������������������������������������������������������������������������������������������� 92


Allocating Memory���������������������������������������������������������������������������������������������������������������������� 93
Persisting Data���������������������������������������������������������������������������������������������������������������������������� 94
Atomic Operations����������������������������������������������������������������������������������������������������������������� 94
Reserve/Publish API�������������������������������������������������������������������������������������������������������������� 97
Transactional API����������������������������������������������������������������������������������������������������������������� 100
Optional Flags���������������������������������������������������������������������������������������������������������������������� 104
Persisting Data Summary���������������������������������������������������������������������������������������������������� 104
Guarantees of libpmemobj’s APIs��������������������������������������������������������������������������������������������� 105
Managing Library Behavior������������������������������������������������������������������������������������������������������� 106
Debugging and Error Handling�������������������������������������������������������������������������������������������������� 106
Summary���������������������������������������������������������������������������������������������������������������������������������� 108

Chapter 8: libpmemobj-cpp: The Adaptable Language - C++ and


Persistent Memory����������������������������������������������������������������������������������������������� 111
Introduction������������������������������������������������������������������������������������������������������������������������������� 111
Metaprogramming to the Rescue��������������������������������������������������������������������������������������������� 112
Persistent Pointers�������������������������������������������������������������������������������������������������������������� 112
Transactions������������������������������������������������������������������������������������������������������������������������ 113
Snapshotting����������������������������������������������������������������������������������������������������������������������� 115
Allocating����������������������������������������������������������������������������������������������������������������������������� 116
C++ Standard limitations���������������������������������������������������������������������������������������������������������� 118
An Object’s Lifetime������������������������������������������������������������������������������������������������������������ 119
Trivial Types������������������������������������������������������������������������������������������������������������������������� 120
Object Layout����������������������������������������������������������������������������������������������������������������������� 122
Pointers������������������������������������������������������������������������������������������������������������������������������� 123
Limitations Summary���������������������������������������������������������������������������������������������������������� 125
Persistence Simplified�������������������������������������������������������������������������������������������������������������� 126
The Ecosystem�������������������������������������������������������������������������������������������������������������������������� 133
Persistent Containers���������������������������������������������������������������������������������������������������������� 134
Examples of Persistent Containers�������������������������������������������������������������������������������������� 135
Summary���������������������������������������������������������������������������������������������������������������������������������� 138

vi
Table of Contents

Chapter 9: pmemkv: A Persistent In-­Memory Key-Value Store���������������������������� 141


pmemkv Architecture���������������������������������������������������������������������������������������������������������������� 143
A Phonebook Example�������������������������������������������������������������������������������������������������������������� 147
Bringing Persistent Memory Closer to the Cloud���������������������������������������������������������������������� 151
Summary���������������������������������������������������������������������������������������������������������������������������������� 152

Chapter 10: Volatile Use of Persistent Memory���������������������������������������������������� 155


Introduction������������������������������������������������������������������������������������������������������������������������������� 155
Background������������������������������������������������������������������������������������������������������������������������������� 156
Memory Allocation��������������������������������������������������������������������������������������������������������������� 156
How it Works����������������������������������������������������������������������������������������������������������������������� 156
Supported “Kinds” of Memory��������������������������������������������������������������������������������������������� 157
The memkind API���������������������������������������������������������������������������������������������������������������������� 159
Kind Management API��������������������������������������������������������������������������������������������������������� 159
Heap Management API�������������������������������������������������������������������������������������������������������� 164
Kind Configuration Management����������������������������������������������������������������������������������������� 167
Additional memkind Code Examples����������������������������������������������������������������������������������� 168
C++ Allocator for PMEM Kind��������������������������������������������������������������������������������������������������� 168
pmem::allocator methods���������������������������������������������������������������������������������������������������� 169
Nested Containers��������������������������������������������������������������������������������������������������������������� 169
C++ Examples�������������������������������������������������������������������������������������������������������������������������� 170
Using the pmem::allocator�������������������������������������������������������������������������������������������������� 170
Creating a Vector of Strings������������������������������������������������������������������������������������������������� 171
Expanding Volatile Memory Using Persistent Memory�������������������������������������������������������������� 173
libvmemcache: An Efficient Volatile Key-Value Cache for Large-Capacity
Persistent Memory�������������������������������������������������������������������������������������������������������������������� 177
libvmemcache Overview����������������������������������������������������������������������������������������������������� 178
libvmemcache Design��������������������������������������������������������������������������������������������������������� 180
Using libvmemcache����������������������������������������������������������������������������������������������������������� 183
Summary���������������������������������������������������������������������������������������������������������������������������������� 186

vii
Table of Contents

Chapter 11: Designing Data Structures for Persistent Memory��������������������������� 187


Contiguous Data Structures and Fragmentation����������������������������������������������������������������������� 187
Internal and External Fragmentation����������������������������������������������������������������������������������� 188
Atomicity and Consistency�������������������������������������������������������������������������������������������������� 189
Selective Persistence���������������������������������������������������������������������������������������������������������� 193
Example Data Structures����������������������������������������������������������������������������������������������������� 193
Summary���������������������������������������������������������������������������������������������������������������������������������� 206

Chapter 12: Debugging Persistent Memory Applications������������������������������������� 207


pmemcheck for Valgrind����������������������������������������������������������������������������������������������������������� 208
Stack Overflow Example������������������������������������������������������������������������������������������������������ 208
Memory Leak Example�������������������������������������������������������������������������������������������������������� 209
Intel Inspector – Persistence Inspector������������������������������������������������������������������������������������ 210
Stack Overflow Example������������������������������������������������������������������������������������������������������ 211
Memory Leak Example�������������������������������������������������������������������������������������������������������� 212
Common Persistent Memory Programming Problems�������������������������������������������������������������� 214
Nonpersistent Stores����������������������������������������������������������������������������������������������������������� 214
Stores Not Added into a Transaction������������������������������������������������������������������������������������ 228
Memory Added to Two Different Transactions��������������������������������������������������������������������� 233
Memory Overwrites������������������������������������������������������������������������������������������������������������� 240
Unnecessary Flushes���������������������������������������������������������������������������������������������������������� 242
Out-of-Order Writes������������������������������������������������������������������������������������������������������������� 247
Summary���������������������������������������������������������������������������������������������������������������������������������� 259

Chapter 13: Enabling Persistence Using a Real-World Application���������������������� 261


The Database Example������������������������������������������������������������������������������������������������������������� 262
Different Persistent Memory Enablement Approaches������������������������������������������������������������� 262
Developing a Persistent Memory-Aware MariaDB* Storage Engine����������������������������������������� 263
Understanding the Storage Layer���������������������������������������������������������������������������������������� 264
Creating a Storage Engine Class����������������������������������������������������������������������������������������� 265
Summary���������������������������������������������������������������������������������������������������������������������������������� 276

viii
Table of Contents

Chapter 14: Concurrency and Persistent Memory������������������������������������������������ 277


Transactions and Multithreading����������������������������������������������������������������������������������������������� 278
Mutexes on Persistent Memory������������������������������������������������������������������������������������������������ 282
Atomic Operations and Persistent Memory������������������������������������������������������������������������������ 285
Lock-Free Algorithms and Persistent Memory�������������������������������������������������������������������� 285
Concurrent Data Structures for Persistent Memory������������������������������������������������������������������ 286
Concurrent Ordered Map����������������������������������������������������������������������������������������������������� 287
Concurrent Hash Map���������������������������������������������������������������������������������������������������������� 291
Summary���������������������������������������������������������������������������������������������������������������������������������� 293

Chapter 15: Profiling and Performance���������������������������������������������������������������� 295


Introduction������������������������������������������������������������������������������������������������������������������������������� 295
Performance Analysis Concepts����������������������������������������������������������������������������������������������� 295
Compute-Bound vs. Memory-Bound����������������������������������������������������������������������������������� 295
Memory Latency vs. Memory Capacity������������������������������������������������������������������������������� 296
Read vs. Write Performance������������������������������������������������������������������������������������������������ 296
Memory Access Patterns����������������������������������������������������������������������������������������������������� 296
I/O Storage Bound Workloads���������������������������������������������������������������������������������������������� 297
Determining the Suitability of Workloads for Persistent Memory��������������������������������������������� 297
Volatile Use Cases��������������������������������������������������������������������������������������������������������������� 298
Use Cases Requiring Persistence���������������������������������������������������������������������������������������� 301
Performance Analysis of Workloads Using Persistent Memory������������������������������������������������ 302
Characterizing the Workload����������������������������������������������������������������������������������������������� 303
Memory Bandwidth and Latency����������������������������������������������������������������������������������������� 303
Persistent Memory Read-Write Ratio���������������������������������������������������������������������������������� 305
Working Set Size and Memory Footprint����������������������������������������������������������������������������� 305
Non-Uniform Memory Architecture (NUMA) Behavior��������������������������������������������������������� 305
Optimizing the Software for Persistent Memory����������������������������������������������������������������� 307
Summary���������������������������������������������������������������������������������������������������������������������������������� 311

ix
Table of Contents

Chapter 16: PMDK Internals: Important Algorithms and Data Structures������������ 313
A Pool of Persistent Memory: High-Level Architecture Overview��������������������������������������������� 313
The Uncertainty of Memory Mapping: Persistent Memory Object Identifier����������������������������� 315
Persistent Thread Local Storage: Using Lanes�������������������������������������������������������������������������� 318
Ensuring Power-Fail Atomicity: Redo and Undo Logging���������������������������������������������������������� 320
Transaction Redo Logging��������������������������������������������������������������������������������������������������� 320
Transaction Undo Logging��������������������������������������������������������������������������������������������������� 321
libpmemobj Unified Logging������������������������������������������������������������������������������������������������ 322
Persistent Allocations: The Interface of a Transactional Persistent Allocator���������������������������� 323
Persistent Memory Heap Management: Allocator Design for Persistent Memory�������������������� 324
ACID Transactions: Efficient Low-Level Persistent Transactions����������������������������������������������� 328
Lazy Reinitialization of Variables: Storing the Volatile State on Persistent Memory����������������� 330
Summary���������������������������������������������������������������������������������������������������������������������������������� 331

Chapter 17: Reliability, Availability, and Serviceability (RAS)������������������������������ 333


Dealing with Uncorrectable Errors�������������������������������������������������������������������������������������������� 333
Consumed Uncorrectable Error Handling���������������������������������������������������������������������������� 334
Unconsumed Uncorrectable Error Handling������������������������������������������������������������������������ 336
Clearing Uncorrectable Errors��������������������������������������������������������������������������������������������� 339
Device Health���������������������������������������������������������������������������������������������������������������������������� 339
ACPI-Defined Health Functions (_NCH, _NBS)��������������������������������������������������������������������� 342
Vendor-Specific Device Health (_DSMs)������������������������������������������������������������������������������ 342
ACPI NFIT Health Event Notification������������������������������������������������������������������������������������ 343
Unsafe/Dirty Shutdown������������������������������������������������������������������������������������������������������������� 343
Application Utilization of Data Loss Count (DLC)����������������������������������������������������������������� 344
Summary���������������������������������������������������������������������������������������������������������������������������������� 346

Chapter 18: Remote Persistent Memory��������������������������������������������������������������� 347


RDMA Networking Protocols����������������������������������������������������������������������������������������������������� 348
Goals of the Initial Remote Persistent Memory Architecture���������������������������������������������������� 351
Guaranteeing Remote Persistence�������������������������������������������������������������������������������������������� 351
General-Purpose Remote Replication Method��������������������������������������������������������������������� 353

x
Table of Contents

Appliance Remote Replication Method�������������������������������������������������������������������������������� 355


General Software Architecture�������������������������������������������������������������������������������������������������� 357
librpmem Architecture and Its Use in Replication��������������������������������������������������������������������� 358
Configuring Remote Replication Using Poolsets����������������������������������������������������������������� 362
Performance Considerations����������������������������������������������������������������������������������������������� 362
Remote Replication Error Handling������������������������������������������������������������������������������������� 364
Say Hello to the Replicated World��������������������������������������������������������������������������������������� 364
Summary���������������������������������������������������������������������������������������������������������������������������������� 370

Chapter 19: Advanced Topics������������������������������������������������������������������������������� 373


Nonuniform Memory Access (NUMA)���������������������������������������������������������������������������������������� 373
NUMACTL Linux Utility��������������������������������������������������������������������������������������������������������� 374
NDCTL Linux Utility�������������������������������������������������������������������������������������������������������������� 376
Intel Memory Latency Checker Utility���������������������������������������������������������������������������������� 378
NUMASTAT Utility����������������������������������������������������������������������������������������������������������������� 380
Intel VTune Profiler – Platform Profiler�������������������������������������������������������������������������������� 381
IPMCTL Utility���������������������������������������������������������������������������������������������������������������������� 381
BIOS Tuning Options������������������������������������������������������������������������������������������������������������ 382
Automatic NUMA Balancing������������������������������������������������������������������������������������������������� 382
Using Volume Managers with Persistent Memory�������������������������������������������������������������������� 383
The mmap( ) MAP_SYNC Flag��������������������������������������������������������������������������������������������������� 385
Summary���������������������������������������������������������������������������������������������������������������������������������� 386

Appendix A: How to Install NDCTL and DAXCTL on Linux������������������������������������� 389


Prerequisites����������������������������������������������������������������������������������������������������������������������������� 389
Installing NDCTL and DAXCTL Using the Linux Distribution Package Repository���������������������� 390
Searching for Packages Within a Package Repository�������������������������������������������������������� 391
Installing NDCTL and DAXCTL from the Package Repository���������������������������������������������� 392

xi
Table of Contents

Appendix B: How to Install the Persistent Memory Development Kit (PMDK)������ 395
PMDK Prerequisites������������������������������������������������������������������������������������������������������������������ 395
Installing PMDK Using the Linux Distribution Package Repository������������������������������������������� 395
Package Naming Convention����������������������������������������������������������������������������������������������� 396
Searching for Packages Within a Package Repository�������������������������������������������������������� 396
Installing PMDK Libraries from the Package Repository����������������������������������������������������� 398
Installing PMDK on Microsoft Windows������������������������������������������������������������������������������������ 402

Appendix C: How to Install IPMCTL on Linux and Windows���������������������������������� 403


IPMCTL Linux Prerequisites������������������������������������������������������������������������������������������������������ 404
libsafec�������������������������������������������������������������������������������������������������������������������������������� 404
IPMCTL Linux Packages������������������������������������������������������������������������������������������������������������ 404
IPMCTL for Microsoft Windows������������������������������������������������������������������������������������������������� 404
Using ipmctl������������������������������������������������������������������������������������������������������������������������������ 405

Appendix D: Java for Persistent Memory������������������������������������������������������������� 411


Volatile Use of Persistent Memory�������������������������������������������������������������������������������������������� 411
Heap Allocation on Alternative Memory Devices����������������������������������������������������������������� 412
Persistent Collections for Java (PCJ)���������������������������������������������������������������������������������������� 416
Using PCJ in Java Applications������������������������������������������������������������������������������������������������� 417
Low-Level Persistent Library (LLPL)����������������������������������������������������������������������������������������� 418
Using LLPL in Java Applications������������������������������������������������������������������������������������������������ 419
Summary���������������������������������������������������������������������������������������������������������������������������������� 419

Appendix E: The Future of Remote Persistent Memory Replication��������������������� 421

Glossary���������������������������������������������������������������������������������������������������������������� 425

Index��������������������������������������������������������������������������������������������������������������������� 429

xii
About the Author
Steve Scargall is a persistent memory software and cloud architect at Intel
Corporation. As a technology evangelist, he supports the enabling and development
effort to integrate persistent memory technology into software stacks, applications,
and hardware architectures. This includes working with independent software
vendors (ISVs) on both proprietary and open source development, original equipment
manufacturers (OEMs), and cloud service providers (CSPs).

Steve holds a Bachelor of Science in computer science and cybernetics from the
University of Reading, UK, where he studied neural networks, AI, and robotics. He
has over 19 years’ experience providing performance analysis on x86 architecture and
SPARC for Solaris Kernel, ZFS, and UFS file system. He performed DTrace debugging in
enterprise and cloud environments during his tenures at Sun Microsystems and Oracle.

xiii
About the Technical Reviewer
Andy Rudoff is a principal engineer at Intel Corporation, focusing on non-volatile
memory programming. He is a contributor to the SNIA NVM Programming Technical
Work Group. His more than 30 years’ industry experience includes design and
development work in operating systems, file systems, networking, and fault management
at companies large and small, including Sun Microsystems and VMware. Andy has
taught various operating systems classes over the years and is a coauthor of the popular
UNIX Network Programming textbook.

xv
About the Contributors
Piotr Balcer is a software engineer at Intel Corporation with many years’ experience
working on storage-related technologies. He holds a Bachelor of Science in engineering
from the Gdańsk University of Technology, Poland, where he studied system software
engineering. Piotr has been working on the software ecosystem for next-generation
persistent memory since 2014.

Eduardo Berrocal joined Intel Corporation as a cloud software engineer in 2017 after
receiving his PhD in computer science from the Illinois Institute of Technology. His
doctoral research focused on data analytics and fault tolerance for high-performance
computing. Past experience includes working as an intern at Bell Labs (Nokia), a research
aid at Argonne National Laboratory, a scientific programmer and web developer at the
University of Chicago, and an intern in the CESVIMA laboratory in Spain.

Adam Borowski is a software engineer at Intel Corporation, hailing from the


University of Warsaw, Poland. He is a Debian developer and has made many open
source contributions over the past two decades. Adam is currently working on
persistent memory stacks, both on upstream code and integrating it with downstream
distributions.

Igor Chorazewicz is a software engineer at Intel Corporation. His main focus is on


persistent memory data structures and enabling C++ applications for persistent
memory. Igor holds a Bachelor of Science in engineering from the Gdańsk University of
Technology, Poland.

Adam Czapski is a technical writer at Intel Corporation. He writes technical


documentation in the Data Center Group and is currently working in the persistent
memory department. Adam holds a Bachelor of Arts in English philology and a master’s
degree in natural language processing from the Gdańsk University of Technology, Poland.

Steve Dohrmann is a software engineer at Intel Corporation. He has worked on a variety


of projects over the past 20 years, including media frameworks, mobile agent software,
secure collaboration software, and parallel programming language implementation. He
is currently working on enabling the use of persistent memory in Java*.

xvii
About the Contributors

Chet Douglas is a principal software engineer at Intel Corporation and focuses on cloud
software architecture along with operating system and OEM enabling of non-volatile
memory technologies. He has over 14 years’ experience working on various enterprise
and client programs and 28 years of total storage experience. Chet has worked in all
aspects of storage, including storage controller hardware design, SCSI disk/tape/CD
writer firmware architecture, storage management software architecture, Microsoft
Windows* and Linux kernel-mode drivers, enterprise hardware RAID, and client/
workstation software RAID. He holds seven storage-related hardware and software
patents and has a dual Bachelor of Science in electrical engineering and computer
engineering from Clarkson University, New York.

Ken Gibson is the director of persistent memory software architecture within Intel
Corporation’s Data Center Group. Since 2012, Ken and his team have been working with
Intel’s server and software partners to create the open persistent memory programming
model.

Tomasz Gromadzki is a software architect in Intel Corporation’s Non-Volatile Memory


Solutions Group. His focus is on remote persistent memory access, which includes
proper integration of persistent memory with other (networking) technologies as well as
optimal persistent memory replication procedures and algorithms.

Kishor Kharbas is a software engineer on the Java runtime engineering team at Intel
Corporation. For the past eight years, he has been working to optimize Oracle’s OpenJDK
on Intel platforms. This involves Java garbage collection and compiler back-end
optimization.

Jackson Marusarz is a senior technical consulting engineer (TCE) in Intel Corporation's


Compute Performance and Developer Products Division. As the lead TCE for Intel
VTune Profiler, his main focus is on software performance analysis and tuning for both
serial and multithreaded applications. Jackson’s time is split between determining how
to analyze and tune software and creating tools that help others do the same.

Jan Michalski is a software engineer in Intel Corporation’s Non-­Volatile Memory


Solutions Group. His focus is on remote persistent memory access, which includes
proper integration of persistent memory with other technologies, as well as looking for
optimal persistent memory replication procedures and algorithms. He holds a master's
degree in computer engineering from the Gdańsk University of Technology, Poland,
where he studied system software engineering.

xviii
About the Contributors

Nicholas Moulin is a cloud software architect at Intel Corporation. Since joining Intel
in 2012, he has focused on enabling and developing persistent memory software for
operating systems and platform firmware and managing persistent memory hardware.
Nicholas is currently working with industry partners to define and improve RAS features
relevant to the persistent memory programming model.

Szymon Romik is a software engineer at Intel Corporation and is currently focused on


persistent memory programming. He previously worked as a lead software engineer
on 5G technologies at Ericsson. Szymon holds a master’s degree in mathematics from
Jagiellonian University, Poland.

Jakub Schmiegel is a software architect in Intel Corporation’s Non-Volatile Memory


Solutions Group where he has been focused on enabling existing applications to
persistent memory and analyzing their performance for more than four years. Jakub
holds a master’s degree in computer science from the Gdańsk University of Technology,
Poland.

Kevin Shalkowsky is a Telly Award–winning creative director, graphic designer, and


animator with more than a decade of experience. While his contributions are in
technology today, Kevin has spent time in broadcast journalism and selling numerous
products through 30-minute late-night infomercials. He resides in Oregon with his wife
and son. From time to time, you can find Kevin lost in the woods, lost in a parking lot,
or lost in his design process – but this somehow got him to where he is today, and he
wouldn’t have it any other way.

Vineet Singh is a memory and storage tools software engineer at Intel Corporation.
He develops techniques to help developers adapt to the latest memory technologies.
Vineet holds a PhD in philosophy from the University of California and has a Bachelor
of Technology degree from the Indian Institute of Information Technology, Design, and
Manufacturing in Jabalpur.

Pawel Skowron is a software engineering manager at Intel Corporation with 20 years'


experience in the software industry. Pawel has worked in various roles related to the
whole-software development life cycle. His software engineering background lies in the
areas of embedded systems, database systems, and applications. For the past few years,
Pawel has led the development and validation of the Persistent Memory Development
Kit (https://github.com/pmem/pmdk).

xix
About the Contributors

Usha Upadhyayula has been with Intel Corporation for 20 years serving in many
different roles. Usha holds a master’s degree in computer science from the University
of South Carolina, and she spent the first few years at Intel developing user-level
applications in C and C++. She later moved to customer-­enabling roles for Intel media
processors and support for Intel RAID software. Usha is currently part of the Data Center
Group where she is focused on enabling cloud service providers to fully utilize and
accelerate the adoption of Intel persistent memory products.

Sergey Vinogradov is a senior software development engineer at Intel Corporation


where he spent more than seven years working on performance profiling tools and
threading runtime libraries. During the past four years, Sergey has been working on C++
programming models and performance profiling methodologies for persistent memory.

xx
Acknowledgments
First and foremost, I would like to thank Ken Gibson for masterminding this book idea
and for gifting me the pleasure of writing and managing it. Your support, guidance, and
contributions have been instrumental in delivering a high-quality product.
If the Vulcan mind-meld or The Matrix Headjack were possible, I could have cloned
Andy Rudoff’s mind and allowed him to work on his daily activities. Instead, Andy’s
infinite knowledge of persistent memory had to be tapped through good old verbal
communication and e-mail. I sincerely thank you for devoting so much time to me and
this project. The results read for themselves.
Debbie Graham was instrumental in helping me manage this colossal project. Her
dedication and support helped drive the project to an on-time completion.
To my friends and colleagues at Intel who contributed content, supported
discussions, helped with decision-making, and reviewed drafts during the book-writing
process. These are the real heroes. Without your heavily invested time and support, this
book would have taken considerably longer to complete. It is a much better product as a
result of the collaborative effort. A huge thanks to all of you.
I'd like to express my sincerest gratitude and appreciation to the people at Apress,
without whom this book could not have been published. From the initial contact and
outline discussions through the entire publishing process to this final polished product,
the Apress team delivered continuous support and assistance. Many thanks to Susan,
Jessica, and Rita. It was a real pleasure working with you.

xxi
Preface
About This Book
Persistent memory is often referred to as non-volatile memory (NVM) or storage
class memory (SCM). In this book, we purposefully use persistent memory as an all-­
encompassing term to represent all the current and future memory technologies that
fall under this umbrella. This book introduces the persistent memory technology and
provides answers to key questions. For software developers, those questions include:
What is persistent memory? How do I use it? What APIs and libraries are available?
What benefits can it provide for my application? What new programming methods do I
need to learn? How do I design applications to use persistent memory? Where can I find
information, documentation, and help?
System and cloud architects will be provided with answers to questions such as:
What is persistent memory? How does it work? How is it different than DRAM or SSD/
NVMe storage devices? What are the hardware and operating system requirements?
What applications need or could benefit from persistent memory? Can my existing
applications use persistent memory without being modified?
Persistent memory is not a plug-and-play technology for software applications.
Although it may look and feel like traditional DRAM memory, applications need to be
modified to fully utilize the persistence feature of persistent memory. That is not to say
that applications cannot run unmodified on systems with persistent memory installed,
they can, but they will not see the full potential of what persistent memory offers without
code modification.
Thankfully, server and operating system vendors collaborated very early in the
design phase and already have products available on the market. Linux and Microsoft
Windows already provide native support for persistent memory technologies. Many
popular virtualization technologies also support persistent memory.
For ISVs and the developer community at large, the journey is just beginning. Some
software has already been modified and is available on the market. However, it will
take time for the enterprise and cloud computing industries to adopt and make the
hardware available to the general marketplace. ISVs and software developers need time
to understand what changes to existing applications are required and implement them.
xxiii
Preface

To make the required development work easier, Intel developed and open sourced
the Persistent Memory Development Kit (PMDK) available from https://pmem.io/
pmdk/. We introduce the PMDK in more detail in Chapter 5 and walk through most of
the available libraries in subsequent chapters. Each chapter provides an in-depth guide
so developers can understand what library or libraries to use. PMDK is a set of open
source libraries and tools based on the Storage Networking Industry Association (SNIA)
NVM programming model designed and implemented by over 50 industry partners. The
latest NVM programming model document can be found at https://www.snia.org/
tech_activities/standards/curr_standards/npm. The model describes how software
can utilize persistent memory features and enables designers to develop APIs that take
advantage of NVM features and performance.
Available for both Linux and Windows, PMDK facilitates persistent memory
programming adoption with higher-level language support. C and C++ support is fully
validated. Support for other languages such as Java and Python is work in progress
at the time this book was written. Other languages are expected to also adopt the
programming model and provide native persistent memory APIs for developers. The
PMDK development team welcomes and encourages new contributions to core code,
new language bindings, or new storage engines for the persistent memory key-value
store called pmemkv.
This book assumes no prior knowledge of persistent memory hardware devices
or software development. The book layout allows you to freely navigate the content in
the order you want. It is not required to read all chapters in order, though we do build
upon concepts and knowledge described in previous chapters. In such cases, we make
backward and forward references to relevant chapters and sections so you can learn or
refresh your memory.

B
 ook Structure
This book has 19 chapters, each one focusing on a different topic. The book has three
main sections. Chapters 1-4 provide an introduction to persistent memory architecture,
hardware, and operating system support. Chapters 5-16 allow developers to understand
the PMDK libraries and how to use them in applications. Finally, Chapters 17-19 provide
information on advanced topics such as RAS and replication of data using RDMA.

xxiv
Preface

• Chapter 1. Introduction to Persistent Memory – Introduces persistent


memory and dips our toes in the water with a simple persistent key-­
value store example using libpmemkv.

• Chapter 2. Persistent Memory Architecture – Describes the persistent


memory architecture and focuses on the hardware requirements
developers should know.

• Chapter 3. Operating System Support for Persistent Memory –


Provides information relating to operating system changes, new
features, and how persistent memory is seen by the OS.

• Chapter 4. Fundamental Concepts of Persistent Memory


Programming – Builds on the first three chapters and describes the
fundamental concepts of persistent memory programming.

• Chapter 5. Introducing the Persistent Memory Development Kit


(PMDK) – Introduces the Persistent Memory Development Kit
(PMDK), a suite of libraries to assist software developers.

• Chapter 6. libpmem: Low-Level Persistent Memory Support –


Describes and shows how to use libpmem from the PMDK, a low-­level
library providing persistent memory support.

• Chapter 7. libpmemobj: A Native Transactional Object Store –


Provides information and examples using libpmemobj, a C native
object store library from the PMDK.
• Chapter 8. libpmemobj-cpp: The Adaptable Language - C++ and
Persistent Memory – Demonstrates the C++ libpmemobj-cpp object
store from the PMDK, built using C++ headers on top of libpmemobj.

• Chapter 9. pmemkv: A Persistent In-Memory Key-Value Store –


Expands upon the introduction to libpmemkv from Chapter 1 with a
more in-depth discussion using examples.

• Chapter 10. Volatile Use of Persistent Memory – This chapter is


for those who want to take advantage of persistent memory but
do not require data to be stored persistently. libmemkind is a user-
extensible heap manager built on top of jemalloc which enables
control of memory characteristics and a partitioning of the heap

xxv
Preface

between different kinds of memory, including persistent memory.


libvmemcache is an embeddable and lightweight in-memory caching
solution. It is designed to fully take advantage of large-capacity
memory, such as persistent memory with DAX, through memory
mapping in an efficient and scalable way.

• Chapter 11. Designing Data Structures for Persistent Memory –


Provides a wealth of information for designing data structures for
persistent memory.
• Chapter 12. Debugging Persistent Memory Applications – Introduces
tools and walks through several examples for how software developers
can debug persistent memory–enabled applications.

• Chapter 13. Enabling Persistence using a Real-World Application –


Discusses how a real-world application was modified to enable
persistent memory features.

• Chapter 14. Concurrency and Persistent Memory – Describes how


concurrency in applications should be implemented for use with
persistent memory.

• Chapter 15. Profiling and Performance – Teaches performance


concepts and demonstrates how to use the Intel VTune suite of tools
to profile systems and applications before and after code changes are
made.

• Chapter 16. PMDK Internals: Important Algorithms and Data


Structures – Takes us on a deep dive of the PMDK design, architecture,
algorithms, and memory allocator implementation.

• Chapter 17. Reliability, Availability, and Serviceability (RAS) –


Describes the implementation of reliability, availability, and
serviceability (RAS) with the hardware and operating system layers.

• Chapter 18. Remote Persistent Memory – Discusses how applications


can scale out across multiple systems using local and remote persistent
memory.

• Chapter 19. Advanced Topics – Describes things such as NUMA, using


software volume managers, and the mmap() MAP_SYNC flag.

xxvi
Preface

The Appendixes have separate procedures for installing the PMDK and utilities
required for managing persistent memory. We also included an update for Java and the
future of the RDMA protocols. All of this content is considered temporal, so we did not
want to include it in the main body of the book.

Intended Audience
This book has been written for experienced application developers in mind. We
intend the content to be useful to a wider readership such as system administrators
and architects, students, lecturers, and academic research fellows to name but a few.
System designers, kernel developers, and anyone with a vested or passing interest in this
emerging technology will find something useful within this book.
Every reader will learn what persistent memory is, how it works, and how operating
systems and applications can utilize it. Provisioning and managing persistent memory
are vendor specific, so we include some resources in the Appendix sections to avoid
overcomplicating the main chapter content.
Application developers will learn, by example, how to integrate persistent memory
in to existing or new applications. We use examples extensively throughout this book
using a variety of libraries available within the Persistent Memory Development Kit
(PMDK). Example code is provided in a variety of programming languages such as C,
C++, JavaScript, and others. We want developers to feel comfortable using these libraries
in their own projects. The book provides extensive links to resources where you can find
help and information.
System administrators and architects of Cloud, high-performance computing,
and enterprise environments can use most of the content of this book to
understand persistent memory features and benefits to support applications and
developers. Imagine being able to deploy more virtual machines per physical server or
provide applications with this new memory/storage tier such that they can keep more
data closer to the CPU or restart in a fraction of the time they could before while keeping
a warm cache of data.
Students, lecturers, and academic research fellows will also benefit from many
chapters within this book. Computer science classes can learn about the hardware,
operating system features, and programming techniques. Lecturers are free use the
content in student classes or to form the basis of research projects such as new persistent
memory file systems, algorithms, or caching implementations.

xxvii
Preface

We introduce tools that profile the server and applications to better understand CPU,
memory, and disk IO access patterns. Using this knowledge, we show how applications
can be modified to take full advantage of persistence using the Persistent Memory
Development Kit (PMDK).

A Future Reference
The book content has been written to provide value for many years. Industry
specification such as ACPI, UEFI, and the SNIA non-volatile programming model will,
unless otherwise stated by the specification, remain backward compatible as new
versions are released. If new form factors are introduced, the approach to programming
remains the same. We do not limit ourselves to one specific persistent memory vendor
or implementation. In places where it is necessary to describe vendor-specific features
or implementations, we specifically call this out as it may change between vendors or
between product generations. We encourage you to read the vendor documentation for
the persistent memory product to learn more.
Developers using the Persistent Memory Development Kit (PMDK) will retain a stable
API interface. PMDK will deliver new features and performance improvements with each
major release. It will evolve with new persistent memory products, CPU instructions,
platform designs, industry specifications, and operating system feature support.

Source Code Examples


Concepts and source code samples within this book adhere to the vendor neutral
SNIA non-volatile memory programming model. SNIA which is the Storage
Networking Industry Association is a non-profit global organization dedicated to
developing standards and education programs to advance storage and information
technology. The model was designed, developed, and is maintained by the SNIA NVM
Technical Working Group (TWG) which includes many leading operating system,
hardware, and server vendors. You can join this group or find information at https://
www.snia.org/forums/sssi/nvmp.

xxviii
Preface

The code examples provided with this book have been tested and validated using
Intel Optane DC persistent memory. Since the PMDK is vendor neutral, they will also
work on NVDIMM-N devices. PMDK will support any future persistent memory product
that enters the market.
The code examples used throughout this book are current at the time of
publication. All code examples have been validated and tested to ensure they compile
and execute without error. For brevity, some of the examples in this book use assert()
statements to indicate unexpected errors. Any production code would likely replace
these with the appropriate error handling actions which would include friendlier
error messages and appropriate error recovery actions. Additionally, some of the code
examples use different mount points to represent persistent memory aware file systems,
for example “/daxfs”, “/pmemfs”, and “/mnt/pmemfs”. This demonstrates persistent
memory file systems can be mounted and named appropriately for the application, just
like regular block-based file systems. Source code is from the repository that accompanies
this book – https://github.com/Apress/programming-persistent-memory.
Since this is a rapidly evolving technology, the software and APIs references
throughout this book may change over time. While every effort is made to be backward
compatible, sometimes software must evolve and invalidate previous versions. For this
reason, it is therefore expected that some of the code samples may not compile on newer
hardware or operating systems and may need to be changed accordingly.

B
 ook Conventions
This book uses several conventions to draw your attention to specific pieces of
information. The convention used depends on the type of information displayed.

C
 omputer Commands
Commands, programming library, and API function references may be presented in line
with the paragraph text using a monospaced font. For example:
To illustrate how persistent memory is used, let’s start with a sample program
demonstrating the key-value store provided by a library called libpmemkv.

xxix
Preface

Computer Terminal Output


Computer terminal output is usually taken directly from a computer terminal presented
in a monospaced font such as the following example demonstrating cloning the
Persistent Memory Development Kit (PMDK) from the GitHub project:

$ git clone https://github.com/pmem/pmdk


Cloning into 'pmdk'...
remote: Enumerating objects: 12, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 100169 (delta 2), reused 7 (delta 2), pack-reused 100157
Receiving objects: 100% (100169/100169), 34.71 MiB | 4.85 MiB/s, done.
Resolving deltas: 100% (83447/83447), done.

S
 ource Code
Source code examples taken from the accompanying GitHub repository are shown with
relevant line numbers in a monospaced font. Below each code listing is a reference to
the line number or line number range with a brief description. Code comments use
language native styling. Most languages use the same syntax. Single line comments
will use // and block/multiline comments should use /*..*/. An example is shown in
Listing 1.

Listing 1. A sample program using libpmemkv


    37  #include <iostream>
    38  #include "libpmemkv.h"
    39  
    40  using namespace pmemkv;
    41  
    42  /*
    43   * kvprint -- print a single key-value pair
    44   */
    45  void kvprint(const string& k, const string& v) {
    46      std::cout << "key: " << k << ", value: " << v << "\n";
    47  }

xxx
Preface

• Line 45: Here we define a small helper routine, kvprint(), which prints
a key-value pair when called.

Notes
We use a standard format for notes, cautions, and tips when we want to direct your
attention to an important point, for example.

Note Notes are tips, shortcuts, or alternative approaches to the current


discussion topic. Ignoring a note should have no negative consequences, but you
might miss out on a nugget of information that makes your life easier.

xxxi
CHAPTER 1

Introduction to Persistent
Memory Programming
This book describes programming techniques for writing applications that use persistent
memory. It is written for experienced software developers, but we assume no previous
experience using persistent memory. We provide many code examples in a variety of
programming languages. Most programmers will understand these examples, even if
they have not previously used the specific language.

Note All code examples are available on a GitHub repository (https://


github.com/Apress/programming-persistent-memory), along with
instructions for building and running it.

Additional documentation for persistent memory, example programs, tutorials, and


details on the Persistent Memory Development Kit (PMDK), which is used heavily in this
book, can be found on http://pmem.io.
The persistent memory products on the market can be used in various ways, and
many of these ways are transparent to applications. For example, all persistent memory
products we encountered support the storage interfaces and standard file API’s just like
any solid-state disk (SSD). Accessing data on an SSD is simple and well-understood, so
we consider these use cases outside the scope of this book. Instead, we concentrate on
memory-style access, where applications manage byte-addressable data structures that
reside in persistent memory. Some use cases we describe are volatile, using the persistent
memory only for its capacity and ignoring the fact it is persistent. However, most of this
book is dedicated to the persistent use cases, where data structures placed in persistent
memory are expected to survive crashes and power failures, and the techniques
described in this book keep those data structures consistent across those events.

1
© The Author(s) 2020
S. Scargall, Programming Persistent Memory, https://doi.org/10.1007/978-1-4842-4932-1_1
Chapter 1 Introduction to Persistent Memory Programming

A High-Level Example Program


To illustrate how persistent memory is used, we start with a sample program
demonstrating the key-value store provided by a library called libpmemkv. Listing 1-1
shows a full C++ program that stores three key-value pairs in persistent memory and
then iterates through the key-value store, printing all the pairs. This example may seem
trivial, but there are several interesting components at work here. Descriptions below the
listing show what the program does.

Listing 1-1. A sample program using libpmemkv

    37  #include <iostream>
    38  #include <cassert>
    39  #include <libpmemkv.hpp>
    40
    41  using namespace pmem::kv;
    42  using std::cerr;
    43  using std::cout;
    44  using std::endl;
    45  using std::string;
    46
    47  /*
    48   * for this example, create a 1 Gig file
    49   * called "/daxfs/kvfile"
    50   */
    51  auto PATH = "/daxfs/kvfile";
    52  const uint64_t SIZE = 1024 * 1024 * 1024;
    53
    54  /*
    55   * kvprint -- print a single key-value pair
    56   */
    57  int kvprint(string_view k, string_view v) {
    58      cout << "key: "    << k.data() <<
    59          " value: " << v.data() << endl;
    60      return 0;
    61  }
    62
2
Chapter 1 Introduction to Persistent Memory Programming

    63  int main() {
    64      // start by creating the db object
    65      db *kv = new db();
    66      assert(kv != nullptr);
    67
    68      // create the config information for
    69      // libpmemkv's open method
    70      config cfg;
    71
    72      if (cfg.put_string("path", PATH) != status::OK) {
    73          cerr << pmemkv_errormsg() << endl;
    74          exit(1);
    75      }
    76      if (cfg.put_uint64("force_create", 1) != status::OK) {
    77          cerr << pmemkv_errormsg() << endl;
    78          exit(1);
    79      }
    80      if (cfg.put_uint64("size", SIZE) != status::OK) {
    81          cerr << pmemkv_errormsg() << endl;
    82          exit(1);
    83      }
    84
    85
    86      // open the key-value store, using the cmap engine
    87      if (kv->open("cmap", std::move(cfg)) != status::OK) {
    88          cerr << db::errormsg() << endl;
    89          exit(1);
    90      }
    91
    92      // add some keys and values
    93      if (kv->put("key1", "value1") != status::OK) {
    94          cerr << db::errormsg() << endl;
    95          exit(1);
    96      }

3
Chapter 1 Introduction to Persistent Memory Programming

    97      if (kv->put("key2", "value2") != status::OK) {


    98          cerr << db::errormsg() << endl;
    99          exit(1);
   100      }
   101      if (kv->put("key3", "value3") != status::OK) {
   102          cerr << db::errormsg() << endl;
   103          exit(1);
   104      }
   105
   106      // iterate through the key-value store, printing them
   107      kv->get_all(kvprint);
   108
   109      // stop the pmemkv engine
   110      delete kv;
   111
   112      exit(0);
   113  }

• Line 57: We define a small helper routine, kvprint(), which prints a


key-value pair when called.
• Line 63: This is the first line of main() which is where every C++
program begins execution. We start by instantiating a key-value
engine using the engine name "cmap". We discuss other engine types
in Chapter 9.
• Line 70: The cmap engine takes config parameters from a config
structure. The parameter "path" is configured to "/daxfs/kvfile",
which is the path to a persistent memory file on a DAX file system;
the parameter "size" is set to SIZE. Chapter 3 describes how to
create and mount DAX file systems.
• Line 93: We add several key-value pairs to the store. The trademark
of a key-value store is the use of simple operations like put() and
get(); we only show put() in this example.
• Line 107: Using the get_all() method, we iterate through the
entire key-value store, printing each pair when get_all() calls our
kvprint() routine.
4
Chapter 1 Introduction to Persistent Memory Programming

W
 hat’s Different?
A wide variety of key-value libraries are available in practically every programming
language. The persistent memory example in Listing 1-1 is different because the key-­
value store itself resides in persistent memory. For comparison, Figure 1-1 shows how a
key-value store using traditional storage is laid out.

Figure 1-1. A key-value store on traditional storage

When the application in Figure 1-1 wants to fetch a value from the key-value store,
a buffer must be allocated in memory to hold the result. This is because the values are
kept on block storage, which cannot be addressed directly by the application. The only
way to access a value is to bring it into memory, and the only way to do that is to read
full blocks from the storage device, which can only be accessed via block I/O. Now
consider Figure 1-2, where the key-value store resides in persistent memory like our
sample code.

5
Chapter 1 Introduction to Persistent Memory Programming

Figure 1-2. A key-value store in persistent memory

With the persistent memory key-value store, values are accessed by the application
directly, without the need to first allocate buffers in memory. The kvprint() routine in
Listing 1-1 will be called with references to the actual keys and values, directly where
they live in persistence – something that is not possible with traditional storage. In
fact, even the data structures used by the key-value store library to organize its data are
accessed directly. When a storage-based key-value store library needs to make a small
update, for example, 64 bytes, it must read the block of storage containing those 64 bytes
into a memory buffer, update the 64 bytes, and then write out the entire block to make it
persistent. That is because storage accesses can only happen using block I/O, typically
4K bytes at a time, so the task to update 64 bytes requires reading 4K and then writing
4K. But with persistent memory, the same example of changing 64 bytes would only
write the 64 bytes directly to persistence.

The Performance Difference


Moving a data structure from storage to persistent memory does not just mean smaller
I/O sizes are supported; there is a fundamental performance difference. To illustrate this,
Figure 1-3 shows a hierarchy of latency among the different types of media where data
can reside at any given time in a program.

6
Chapter 1 Introduction to Persistent Memory Programming

Figure 1-3. The memory/storage hierarchy pyramid with estimated latencies

As the pyramid shows, persistent memory provides latencies similar to memory,


measured in nanoseconds, while providing persistency. Block storage provides
persistency with latencies starting in the microseconds and increasing from there,
depending on the technology. Persistent memory is unique in its ability to act like both
memory and storage at the same time.

Program Complexity
Perhaps the most important point of our example is that the programmer still uses
the familiar get/put interfaces normally associated with key-value stores. The fact that
the data structures are in persistent memory is abstracted away by the high-level API
provided by libpmemkv. This principle of using the highest level of abstraction possible,
as long as it meets the application’s needs, will be a recurring theme throughout this
book. We start by introducing very high-level APIs; later chapters delve into the lower-­
level details for programmers who need them. At the lowest level, programming directly
to raw persistent memory requires detailed knowledge of things like hardware atomicity,
cache flushing, and transactions. High-level libraries like libpmemkv abstract away all
that complexity and provide much simpler, less error-prone interfaces.

7
Chapter 1 Introduction to Persistent Memory Programming

How Does libpmemkv Work?


All the complexity hidden by high-level libraries like libpmemkv are described more fully
in later chapters, but let’s look at the building blocks used to construct a library like this.
Figure 1-4 shows the full software stack involved when an application uses libpmemkv.

Figure 1-4. The software stack when using libpmemkv

Starting from the bottom of Figure 1-4 and working upward are these components:

• The persistent memory hardware, typically connected to the system


memory bus and accessed using common memory load/store
operations.

• A pmem-aware file system, which is a kernel module that exposes


persistent memory to applications as files. Those files can be memory
mapped to give applications direct access (abbreviated as DAX).
This method of exposing persistent memory was published by SNIA
(Storage Networking Industry Association) and is described in detail
in Chapter 3.

• The libpmem library is part of the PMDK. This library abstracts


away some of the low-level hardware details like cache flushing
instructions.

8
Chapter 1 Introduction to Persistent Memory Programming

• The libpmemobj library is a full-featured transaction and allocation


library for persistent memory. (Chapters 7 and 8 describe libpmemobj
and its C++ cousin in more detail.) If you cannot find data structures
that meet your needs, you will most likely have to implement what
you need using this library, as described in Chapter 11.

• The cmap engine, a concurrent hash map optimized for persistent


memory.
• The libpmemkv library, providing the API demonstrated in Listing 1-1.

• And finally, the application that uses the API provided by libpmemkv.

Although there is quite a stack of components in use here, it does not mean there
is necessarily a large amount of code that runs for each operation. Some components
are only used during the initial setup. For example, the pmem-aware file system is
used to find the persistent memory file and perform permission checks; it is out of the
application’s data path after that. The PMDK libraries are designed to leverage the direct
access allowed by persistent memory as much as possible.

W
 hat’s Next?
Chapters 1 through 3 provide the essential background that programmers need to know to
start persistent memory programming. The stage is now set with a simple example; the next
two chapters provide details about persistent memory at the hardware and operating system
levels. The later and more advanced chapters provide much more detail for those interested.
Because the immediate goal is to get you programming quickly, we recommend
reading Chapters 2 and 3 to gain the essential background and then dive into Chapter 4
where we start to show more detailed persistent memory programming examples.

S
 ummary
This chapter shows how high-level APIs like libpmemkv can be used for persistent
memory programming, hiding complex details of persistent memory from the
application developer. Using persistent memory can allow finer-grained access and
higher performance than block-based storage. We recommend using the highest-level,
simplest APIs possible and only introducing the complexity of lower-level persistent
memory programming as necessary.
9
Chapter 1 Introduction to Persistent Memory Programming

Open Access This chapter is licensed under the terms of the Creative
Commons Attribution 4.0 International License (http://creativecommons.
org/licenses/by/4.0/), which permits use, sharing, adaptation, distribution and
reproduction in any medium or format, as long as you give appropriate credit to the
original author(s) and the source, provide a link to the Creative Commons license and
indicate if changes were made.
The images or other third party material in this chapter are included in the chapter’s
Creative Commons license, unless indicated otherwise in a credit line to the material. If
material is not included in the chapter’s Creative Commons license and your intended
use is not permitted by statutory regulation or exceeds the permitted use, you will need
to obtain permission directly from the copyright holder.

10
CHAPTER 2

Persistent Memory
Architecture
This chapter provides an overview of the persistent memory architecture while focusing
on the hardware to emphasize requirements and decisions that developers need to know.
Applications that are designed to recognize the presence of persistent memory in
a system can run much faster than using other storage devices because data does not
have to transfer back and forth between the CPU and slower storage devices. Because
applications that only use persistent memory may be slower than dynamic random-­
access memory (DRAM), they should decide what data resides in DRAM, persistent
memory, and storage.
The capacity of persistent memory is expected to be many times larger than DRAM;
thus, the volume of data that applications can potentially store and process in place is
also much larger. This significantly reduces the number of disk I/Os, which improves
performance and reduces wear on the storage media.
On systems without persistent memory, large datasets that cannot fit into DRAM
must be processed in segments or streamed. This introduces processing delays as the
application stalls waiting for data to be paged from disk or streamed from the network.
If the working dataset size fits within the capacity of persistent memory and DRAM,
applications can perform in-memory processing without needing to checkpoint or page
data to or from storage. This significantly improves performance.

11
© The Author(s) 2020
S. Scargall, Programming Persistent Memory, https://doi.org/10.1007/978-1-4842-4932-1_2
Chapter 2 Persistent Memory Architecture

Persistent Memory Characteristics


As with every new technology, there are always new things to consider. Persistent
memory is no exception. Consider these characteristics when architecting and
developing solutions:

• Performance (throughput, latency, and bandwidth) of persistent


memory is much better than NAND but potentially slower than
DRAM.

• Persistent memory is durable unlike DRAM. Its endurance is usually


orders of magnitude better than NAND and should exceed the
lifetime of the server without wearing out.

• Persistent memory module capacities can be much larger than


DRAM DIMMs and can coexist on the same memory channels.

• Persistent memory-enabled applications can update data in place


without needing to serialize/deserialize the data.

• Persistent memory is byte addressable like memory. Applications


can update only the data needed without any read-modify-write
overhead.

• Data is CPU cache coherent.

• Persistent memory provides direct memory access (DMA) and


remote DMA (RDMA) operations.

• Data written to persistent memory is not lost when power is removed.

• After permission checks are completed, data located on persistent


memory is directly accessible from user space. No kernel code, file
system page caches, or interrupts are in the data path.

12
Chapter 2 Persistent Memory Architecture

• Data on persistent memory is instantly available, that is:

• Data is available as soon as power is applied to the system.

• Applications do not need to spend time warming up caches. They


can access the data immediately upon memory mapping it.

• Data residing on persistent memory has no DRAM footprint


unless the application copies data to DRAM for faster access.

• Data written to persistent memory modules is local to the system.


Applications are responsible for replicating data across systems.

Platform Support for Persistent Memory


Platform vendors such as Intel, AMD, ARM, and others will decide how persistent
memory should be implemented at the lowest hardware levels. We try to provide a
vendor-agnostic perspective and only occasionally call out platform-specific details.
For systems with persistent memory, failure atomicity guarantees that systems can
always recover to a consistent state following a power or system failure. Failure atomicity
for applications can be achieved using logging, flushing, and memory store barriers that
order such operations. Logging, either undo or redo, ensures atomicity when a failure
interrupts the last atomic operation from completion. Cache flushing ensures that
data held within volatile caches reach the persistence domain so it will not be lost if a
sudden failure occurs. Memory store barriers, such as an SFENCE operation on the x86
architecture, help prevent potential reordering in the memory hierarchy, as caches and
memory controllers may reorder memory operations. For example, a barrier ensures
that the undo log copy of the data gets persisted onto the persistent memory before the
actual data is modified in place. This guarantees that the last atomic operation can be
rolled back should a failure occur. However, it is nontrivial to add such failure atomicity
in user applications with low-level operations such as write logging, cache flushing, and
barriers. The Persistent Memory Development Kit (PMDK) was developed to isolate
developers from having to re-implement the hardware intricacies.
Failure atomicity should be a familiar concept, since most file systems implement
and perform journaling and flushing of their metadata to storage devices.

13
Chapter 2 Persistent Memory Architecture

C
 ache Hierarchy
We use load and store operations to read and write to persistent memory rather than
using block-based I/O to read and write to traditional storage. We suggest reading the
CPU architecture documentation for an in-depth description because each successive
CPU generation may introduce new features, methods, and optimizations.
Using the Intel architecture as an example, a CPU cache typically has three
distinct levels: L1, L2, and L3. The hierarchy makes references to the distance
from the CPU core, its speed, and size of the cache. The L1 cache is closest to
the CPU. It is extremely fast but very small. L2 and L3 caches are increasingly
larger in capacity, but they are relatively slower. Figure 2-1 shows a typical CPU
microarchitecture with three levels of CPU cache and a memory controller with
three memory channels. Each memory channel has a single DRAM and persistent
memory attached. On platforms where the CPU caches are not contained within
the power-fail protected domain, any modified data within the CPU caches that has
not been flushed to persistent memory will be lost when the system loses power or
crashes. Platforms that do include CPU caches in the power-fail protected domain
will ensure modified data within the CPU caches are flushed to the persistent
memory should the system crash or loses power. We describe these requirements
and features in the upcoming “Power-Fail Protected Domains” section.

14
Chapter 2 Persistent Memory Architecture

Figure 2-1. CPU cache and memory hierarchy

The L1 (Level 1) cache is the fastest memory in a computer system. In terms of access
priority, the L1 cache has the data the CPU is most likely to need while completing a
specific task. The L1 cache is also usually split two ways, into the instruction cache (L1 I)
and the data cache (L1 D). The instruction cache deals with the information about the
operation that the CPU has to perform, while the data cache holds the data on which the
operation is to be performed.
The L2 (Level 2) cache has a larger capacity than the L1 cache, but it is slower. L2
cache holds data that is likely to be accessed by the CPU next. In most modern CPUs,
the L1 and L2 caches are present on the CPU cores themselves, with each core getting
dedicated caches.
The L3 (Level 3) cache is the largest cache memory, but it is also the slowest of the
three. It is also a commonly shared resource among all the cores on the CPU and may be
internally partitioned to allow each core to have dedicated L3 resources.
Data read from DRAM or persistent memory is transferred through the memory
controller into the L3 cache, then propagated into the L2 cache, and finally the L1 cache
where the CPU core consumes it. When the processor is looking for data to carry out an
operation, it first tries to find it into the L1 cache. If the CPU can find it, the condition is
called a cache hit. If the CPU cannot find the data within the L1 cache, it then proceeds to

15
Chapter 2 Persistent Memory Architecture

search for it first within L2, then L3. If it cannot find the data in any of the three, it tries to
access it from memory. Each failure to find data in a cache is called a cache miss. Failure
to locate the data in memory requires the operating system to page the data into memory
from a storage device.
When the CPU writes data, it is initially written to the L1 cache. Due to ongoing
activity within the CPU, at some point in time, the data will be evicted from the L1 cache
into the L2 cache. The data may be further evicted from L2 and placed into L3 and
eventually evicted from L3 into the memory controller’s write buffers where it is then
written to the memory device.
In a system that does not possess persistent memory, software persists data by writing it
to a non-volatile storage device such as an SSD, HDD, SAN, NAS, or a volume in the cloud.
This protects data from application or system crashes. Critical data can be manually flushed
using calls such as msync(), fsync(), or fdatasync(), which flush uncommitted dirty
pages from volatile memory to the non-volatile storage device. File systems provide fdisk
or chkdsk utilities to check and attempt repairs on damaged file systems if required. File
systems do not protect user data from torn blocks. Applications have a responsibility to
detect and recovery from this situation. That’s why databases, for example, use a variety of
techniques such as transactional updates, redo/undo logging, and checksums.
Applications memory map the persistent memory address range directly into its
own memory address space. Therefore, the application must assume responsibility
for checking and guaranteeing data integrity. The rest of this chapter describes
your responsibilities in a persistent memory environment and how to achieve data
consistency and integrity.

Power-Fail Protected Domains


A computer system may include one or more CPUs, volatile or persistent memory
modules, and non-volatile storage devices such as SSDs or HDDs.
System platform hardware supports the concept of a persistence domain, also called
power-fail protected domains. Depending on the platform, a persistence domain may
include the persistent memory controller and write queues, memory controller write
queues, and CPU caches. Once data has reached the persistence domain, it may be
recoverable during a process that results from a system restart. That is, if data is located
within hardware write queues or buffers protected by power failure, domain applications
should assume it is persistent. For example, if a power failure occurs, the data will be flushed

16
Chapter 2 Persistent Memory Architecture

from the power-fail protected domain using stored energy guaranteed by the platform for
this purpose. Data that has not yet made it into the protected domain will be lost.
Multiple persistence domains may exist within the same system, for example, on
systems with more than one physical CPU. Systems may also provide a mechanism for
partitioning the platform resources for isolation. This must be done in such a way that
SNIA NVM programming model behavior is assured from each compliant volume or file
system. (Chapter 3 describes the programming model as it applies to operating systems
and file systems. The “Detecting Platform Capabilities” section in that chapter describes
the logic that applications should perform to detect platform capabilities including
power failure protected domains. Later chapters provide in-depth discussions into why,
how, and when applications should flush data, if required, to guarantee the data is safe
within the protected domain and persistent memory.)
Volatile memory loses its contents when the computer system’s power is interrupted.
Just like non-volatile storage devices, persistent memory keeps its contents even in the
absence of system power. Data that has been physically saved to the persistent memory
media is called data at rest. Data in-flight has the following meanings:

• Writes sent to the persistent memory device but have not yet been
physically committed to the media

• Any writes that are in progress but not yet complete

• Data that has been temporarily buffered or cached in either the CPU
caches or memory controller

When a system is gracefully rebooted or shut down, the system maintains power
and can ensure all contents of the CPU caches and memory controllers are flushed such
that any in-flight or uncommitted data is successfully written to persistent memory
or non-volatile storage. When an unexpected power failure occurs, and assuming no
uninterruptable power supply (UPS) is available, the system must have enough stored
energy within the power supplies and capacitors dotted around it to flush data before the
power is completely exhausted. Any data that is not flushed is lost and not recoverable.
Asynchronous DRAM Refresh (ADR) is a feature supported on Intel products which
flushes the write-protected data buffers and places the DRAM in self-refresh. This
process is critical during a power loss event or system crash to ensure the data is in a safe
and consistent state on persistent memory. By default, ADR does not flush the processor
caches. A platform that supports ADR only includes persistent memory and the memory
controller’s write pending queues within the persistence domain. This is the reason

17
Chapter 2 Persistent Memory Architecture

data in the CPU caches must be flushed by the application using the CLWB, CLFLUSHOPT,
CLFLUSH, non-temporal stores, or WBINVD machine instructions.
Enhanced Asynchronous DRAM Refresh (eADR) requires that a non-maskable
interrupt (NMI) routine be called to flush the CPU caches before the ADR event can begin.
Applications running on an eADR platform do not need to perform flush operations
because the hardware should flush the data automatically, but they are still required
to perform an SFENCE operation to maintain write order correctness. Stores should be
considered persistent only when they are globally visible, which the SFENCE guarantees.
Figure 2-2 shows both the ADR and eADR persistence domains.

Figure 2-2. ADR and eADR power-fail protection domains

ADR is a mandatory platform requirement for persistent memory. The write


pending queue (WPQ) within the memory controller acknowledges receipt of the data
to the writer once all the data is received. Although the data has not yet made it to the
persistent media, a platform supporting ADR guarantees that it will be successfully
written should a power loss event occur. During a crash or power failure, data that is in-­
flight through the CPU caches can only be guaranteed to be flushed to persistent media
if the platform supports eADR. It will be lost on platforms that only support ADR.
The challenge with extending the persistence domain to include the CPU caches is
that the CPU caches are quite large and it would take considerably more energy than the
capacitors in a typical power supply can practically provide. This means the platform
would have to contain batteries or utilize an external uninterruptable power supply.
Requiring a battery for every server supporting persistent memory is not generally
practical or cost-effective. The lifetime of a battery is typically shorter than the server,

18
Chapter 2 Persistent Memory Architecture

which introduces additional maintenance routines that reduce server uptime. There
is also an environmental impact when using batteries as they must be disposed of
or recycled correctly. It is entirely possible for server or appliance OEMs to include a
battery in their product.
Because some appliance and server vendors plan to use batteries, and because
platforms will someday include the CPU caches in the persistence domain, a property is
available within ACPI such that the BIOS can notify software when the CPU flushes can
be skipped. On platforms with eADR, there is no need for manual cache line flushing.

The Need for Flushing, Ordering, and Fencing


Except for WBINVD, which is a kernel-mode-only operation, the machine instructions
in Table 2-1 (in the “Intel Machine Instructions for Persistent Memory” section)
are supported in user space by Intel and AMD CPUs. Intel adopted the SNIA NVM
programming model for working with persistent memory. This model allows for
direct access (DAX) using byte-addressable operations (i.e., load/store). However, the
persistence of the data in the cache is not guaranteed until it has entered the persistence
domain. The x86 architecture provides a set of instructions for flushing cache lines in
a more optimized way. In addition to existing x86 instructions, such as non-temporal
stores, CLFLUSH, and WBINVD, two new instructions were added: CLFLUSHOPT and
CLWB. Both new instructions must be followed by an SFENCE to ensure all flushes are
completed before continuing. Flushing a cache line using CLWB, CLFLUSHOPT, or CLFLUSH
and using non-temporal stores are all supported from user space. You can find details
for each machine instruction in the software developer manuals for the architecture.
On Intel platforms, for example, this information can be found in the Intel 64 and 32
Architectures Software Developer Manuals (https://software.intel.com/en-us/
articles/intel-sdm).
Non-temporal stores imply that the data being written is not going to be read again
soon, so we bypass the CPU caches. That is, there is no temporal locality, so there is no
benefit to keeping the data in the processor’s cache(s), and there may be a penalty if the
stored data displaces other useful data from the cache(s).
Flushing to persistent memory directly from user space negates calling into the
kernel, which makes it highly efficient. The feature is documented in the SNIA persistent
memory programming model specification as an optimized flush. The specification

19
Chapter 2 Persistent Memory Architecture

document1 describes optimized flush as optionally supported by the platform,


depending on the hardware and operating system support. Despite the CPU support,
it is essential for applications to use only optimized flushes when the operating system
indicates that it is safe to use. The operating system may require the control point
provided by calls like msync() when, for example, there are changes to file system
metadata that need to be written as part of the msync() operation.
To better understand instruction ordering, consider a very simple linked list
example. Our pseudocode described in the following has three simple steps to add a new
node into an existing list that already contains two nodes. These steps are depicted in
Figure 2-3.

1. Create the new node (Node 2).

2. Update the node pointer (next pointer) to point to the last node in
the list (Node 2 → Node 1).

3. Update the head pointer to point at the new node (Head → Node 2).

Figure 2-3 (Step 3) shows that the head pointer was updated in the CPU cached version,
but the Node 2 to Node 1 pointer has not yet been updated in persistent memory. This
is because the hardware can choose which cache lines to commit and the order may not
match the source code flow. If the system or application were to crash at this point, the
persistent memory state would be inconsistent, and the data structure would no longer
be usable.

1
 NIA NVM programming model spec: https://www.snia.org/tech_activities/standards/
S
curr_standards/npm

20
Chapter 2 Persistent Memory Architecture

Figure 2-3. Adding a new node to an existing linked list without a store barrier

To solve this problem, we introduce a memory store barrier to ensure the order of the
write operations is maintained. Starting from the same initial state, the pseudocode now
looks like this:

1. Create the new node.

2. Update the node pointer (next pointer) to point to the last node in
the list, and perform a store barrier/fence operation.
3. Update the head pointer to point at the new node.

Figure 2-4 shows that the addition of the store barrier allows the code to work as
expected and maintains a consistent data structure in the volatile CPU caches and on

21
Random documents with unrelated
content Scribd suggests to you:
PREMIERE PARTIE.
De la formation des fluides aériformes & de leur
décomposition; de la combustion des corps
simples & de la formation des acides.
CHAPITRE PREMIER.

Des combinaisons du calorique & de la formation des fluides


élastiques aériformes.

C 'estun phénomène constant dans la nature & dont la généralité


a été bien établie par Boerhaave, que lorsqu'on échauffe un
corps quelconque, solide ou fluide, il augmente de dimension dans
tous les sens. Les faits sur lesquels on s'est fondé pour restreindre
la généralité de ce principe, ne présentent que des résultats
illusoires, ou du moins dans lesquels se compliquent des
circonstances étrangères qui en imposent: mais lorsqu'on est
parvenu à séparer les effets, & à les rapporter chacun à la cause à
laquelle ils appartiennent, on s'apperçoit que l'écartement des
molécules par la chaleur, est une loi générale & constante de la
Nature.
Si après avoir échauffé jusqu'à un certain point un corps solide,
& en avoir ainsi écarté de plus en plus toutes les molécules, on le
laisse refroidir, ces mêmes molécules se rapprochent les unes des
autres dans la même proportion, suivant laquelle elles avoient été
écartées; le corps repasse par les mêmes degrés d'extension qu'il
avoit parcourus; & si on le ramène à la même température qu'il
avoit en commençant l'expérience, il reprend sensiblement le
volume qu'il avoit d'abord. Mais comme nous sommes bien éloignés
de pouvoir obtenir un degré de froid absolu, comme nous ne
connoissons aucun degré de refroidissement que nous ne puissions
supposer susceptible d'être augmenté, il en résulte que nous
n'avons pas encore pu parvenir à rapprocher le plus qu'il est
possible, les molécules d'aucun corps, & que par conséquent les
molécules d'aucun corps ne se touchent dans la Nature; conclusion
très-singulière & à laquelle cependant il est impossible de se
refuser.
On conçoit que les molécules des corps étant ainsi
continuellement sollicitées par la chaleur à s'écarter les unes des
autres, elles n'auroient aucune liaison entr'elles, & qu'il n'y auroit
aucun corps solide, si elles n'étoient retenues par une autre force
qui tendît à les réunir, & pour ainsi dire à les enchaîner; & cette
force, quelle qu'en soit la cause, a été nommée attraction.
Ainsi les molécules des corps peuvent être considérées comme
obéissant à deux forces, l'une répulsive, l'autre attractive, entre
lesquelles elles sont en équilibre. Tant que la dernière de ces
forces, l'attraction, est victorieuse, le corps demeure dans l'état
solide; si au contraire l'attraction est la plus foible, si la chaleur a
tellement écarté les unes des autres les molécules du corps,
qu'elles soient hors de la sphère d'activité de leur attraction, elles
perdent l'adhérence qu'elles avoient entr'elles & le corps cesse
d'être un solide.
L'eau nous présente continuellement un exemple de ces
phénomènes: au-dessous de zéro du thermomètre françois, elle est
dans l'état solide, & elle porte le nom de glace; au-dessus de ce
même terme, ses molécules cessent d'être retenues par leur
attraction réciproque, & elle devient ce qu'on appelle un liquide:
enfin, au-dessus de 80 degrés, ses molécules obéissent à la
répulsion occasionnée par la chaleur; l'eau prend l'état de vapeur
ou de gaz, & elle se transforme en un fluide aériforme.
On en peut dire autant de tous les corps de la Nature; ils sont
ou solides, ou liquides, ou dans l'état élastique & aériforme, suivant
le rapport qui existe entre la force attractive de leurs molécules & la
force répulsive de la chaleur, ou, ce qui revient au même, suivant le
degré de chaleur auquel ils sont exposés.
Il est difficile de concevoir ces phénomènes sans admettre qu'ils
sont l'effet d'une substance réelle & matérielle, d'un fluide très-
subtil qui s'insinue à travers les molécules de tous les corps & qui
les écarte: & en supposant même que l'existence de ce fluide fût
une hypothèse, on verra dans la suite qu'elle explique d'une
manière très-heureuse les phénomènes de la Nature.
Cette substance, quelle qu'elle soit, étant la cause de la chaleur;
ou en d'autres termes la sensation que nous appellons chaleur,
étant l'effet de l'accumulation de cette substance, on ne peut pas,
dans un langage rigoureux, la désigner par le nom de chaleur;
parce que la même dénomination ne peut pas exprimer la cause &
l'effet. C'est ce qui m'avoit déterminé, dans le Mémoire que j'ai
publié en 1777, (Recueil de l'Académie, page 420,) à la désigner
sous le nom de fluide igné & de matière de la chaleur. Depuis, dans
le travail que nous avons fait en commun M. de Morveau, M.
Berthollet, M. de Fourcroy & moi, sur la réforme du langage
chimique, nous avons cru devoir bannir ces périphrases qui
allongent le discours, qui le rendent plus traînant, moins précis,
moins clair, & qui souvent même ne comportent pas des idées
suffisamment justes. Nous avons en conséquence désigné la cause
de la chaleur, le fluide éminemment élastique qui la produit, par le
nom de calorique. Indépendamment de ce que cette expression
remplit notre objet dans le systême que nous avons adopté, elle a
encore un autre avantage, c'est de pouvoir s'adapter à toutes
sortes d'opinions; puisque rigoureusement parlant, nous ne
sommes pas même obligés de supposer que le calorique soit une
matière réelle: il suffit, comme on le sentira mieux par la lecture de
ce qui va suivre, que ce soit une cause répulsive quelconque qui
écarte les molécules de la matière, & on peut ainsi en envisager les
effets d'une manière abstraite & mathématique.
La lumière est-elle une modification du calorique, ou bien le
calorique est-il une modification de la lumière? C'est sur quoi il est
impossible de prononcer dans l'état actuel de nos connoissances.
Ce qu'il y a de certain, c'est que dans un systême où l'on s'est fait
une loi de n'admettre que des faits, & où l'on évite autant qu'il est
possible de rien supposer au-delà de ce qu'ils présentent, on doit
provisoirement désigner par des noms différens, ce qui produit des
effets différens. Nous distinguerons donc la lumière du calorique;
mais nous n'en conviendrons pas moins que la lumière & le
calorique ont des qualités qui leur sont communes, & que dans
quelques circonstances ils se combinent à peu près de la même
manière, & produisent une partie des mêmes effets.
Ce que je viens de dire suffiroit déjà pour bien déterminer l'idée
qu'on doit attacher au mot de calorique. Mais il me reste une tâche
plus difficile à remplir, c'est de donner des idées justes de la
manière dont le calorique agit sur les corps. Puisque cette matière
subtile pénètre à travers les pores de toutes les substances que
nous connoissons, puisqu'il n'existe pas de vases à travers lesquels
elle ne s'échappe, & qu'il n'en est par conséquent aucun qui puisse
la contenir sans perte; on ne peut en connoître les propriétés que
par des effets qui, la plupart, sont fugitifs & difficiles à saisir. C'est
sur les choses qu'on ne peut ni voir, ni palper, qu'il est sur-tout
important de se tenir en garde contre les écarts de l'imagination,
qui tend toujours à s'élancer au-delà du vrai, & qui a bien de la
peine à se renfermer dans le cercle étroit que les faits lui
circonscrivent.
Nous venons de voir que le même corps devenoit solide ou
liquide, ou fluide aériforme, suivant la quantité de calorique dont il
étoit pénétré, ou, pour parler d'une manière plus rigoureuse,
suivant que la force répulsive du calorique étoit égale à l'attraction
de ses molécules, ou qu'elle étoit plus forte, ou plus foible qu'elle.
Mais s'il n'existoit que ces deux forces, les corps ne seroient
liquides qu'à un degré indivisible du thermomètre, & ils passeroient
brusquement de l'état de solide à celui de fluide élastique
aériforme. Ainsi l'eau, par exemple, à l'instant même où elle cesse
d'être glace, commenceroit à bouillir; elle se transformeroit en un
fluide aériforme, & ses molécules s'écarteroient indéfiniment dans
l'espace: s'il n'en est pas ainsi, c'est qu'une troisième force, la
pression de l'atmosphère, met obstacle à cet écartement, & c'est
par cette raison que l'eau demeure dans l'état fluide depuis zéro
jusqu'à 80 degrés du thermomètre françois; la quantité de
calorique qu'elle reçoit dans cet intervalle est insuffisante pour
vaincre l'effort occasionné par la pression de l'atmosphère.
On voit donc que, sans la pression de l'atmosphère, nous
n'aurions pas de liquide constant; nous ne verrions les corps dans
cet état qu'au moment précis où ils se fondent: la moindre
augmentation de chaleur qu'ils recevroient ensuite, en écarteroit
sur le champ les parties & les disperseroit. Il y a plus, sans la
pression de l'atmosphère, nous n'aurions pas, à proprement parler,
de fluides aériformes. En effet, au moment où la force de
l'attraction seroit vaincue par la force répulsive du calorique, les
molécules s'éloigneroient indéfiniment, sans que rien limitât leur
écartement, si ce n'est leur propre pesanteur qui les rassembleroit
pour former une atmosphère.
De simples réflexions sur les expériences les plus connues,
suffisent pour faire appercevoir la vérité de ce que je viens
d'énoncer. Elle se trouve d'ailleurs confirmée d'une manière
évidente par l'expérience qui suit, dont j'ai déjà donné le détail à
l'Académie en 1777. (Voyez Mém. page 426.)
On remplit d'éther sulfurique[2] un petit vase de verre étroit, A,
planche VII, fig. 17, monté sur son pied P. Ce vase ne doit pas
avoir plus de douze à quinze lignes de diamètre & environ deux
pouces de hauteur. On couvre ce vase avec une vessie humectée,
qu'on assujettit autour du col du vase par un grand nombre de
tours de gros fil bien serrés: pour plus grande sûreté, on remet une
seconde vessie par-dessus la première, & on l'assujettit de la même
manière. Ce vase doit être tellement rempli d'éther qu'il ne reste
aucune portion d'air entre la liqueur & la vessie; on le place ensuite
sous le récipient BCD, d'une machine pneumatique dont le haut B
doit être garni d'une boëte à cuir, traversée par une tige EF, dont
l'extrêmité F se termine en une pointe ou lame très-aigue: à ce
même récipient doit être adapté un baromètre GH.
Lorsque tout est ainsi disposé, on fait le vuide sous le récipient;
puis en faisant descendre la tige pointue EF, on crève la vessie.
Aussi-tôt l'éther commence à bouillir avec une étonnante rapidité, il
se vaporise & se transforme en un fluide élastique aériforme, qui
occupe tout le récipient. Si la quantité d'éther est assez
considérable pour que, la vaporisation finie, il en reste encore
quelques goutes dans la fiole, le fluide élastique qui s'est produit
est susceptible de soutenir le baromètre adapté à la machine
pneumatique à huit ou dix pouces environ pendant l'hiver, & à vingt
& vingt-cinq pendant les chaleurs de l'été. On peut, pour rendre
cette expérience plus complette, introduire un petit thermomètre
dans le vase A qui contient l'éther, & on s'apperçoit qu'il descend
considérablement pendant tout le tems que dure la vaporisation.
On ne fait autre chose, dans cette expérience, que de supprimer
le poids de l'atmosphère, qui, dans l'état ordinaire, pèse sur la
surface de l'éther, & les effets qui en résultent prouvent
évidemment deux choses: la première, qu'au degré de température
dans lequel nous vivons, l'éther seroit constamment dans l'état d'un
fluide aériforme, si la pression de l'atmosphère n'y mettoit obstacle.
La seconde, que ce passage de l'état liquide à l'état aériforme, est
accompagné d'un refroidissement considérable, par la raison que
pendant la vaporisation, une partie du calorique, qui étoit dans un
état de liberté, ou au moins d'équilibre dans les corps environnans,
se combine avec l'éther pour le porter à l'état de fluide aériforme.
La même expérience réussit avec tous les fluides évaporables,
tels que l'esprit-de-vin ou alkool, l'eau & le mercure même; avec
cette différence cependant que l'atmosphère d'alkool qui se forme
sous le récipient, ne peut soutenir le baromètre adapté à la
machine pneumatique, en hiver, qu'à un pouce au-dessus de son
niveau, & à quatre ou cinq en été; que l'eau ne le soutient qu'à
quelques lignes, & le mercure à quelques fractions de ligne. Il y a
donc moins de fluide vaporisé lorsqu'on opère avec l'alkool, que
lorsqu'on opère avec l'éther; moins encore avec l'eau, & sur-tout
avec le mercure: par conséquent moins de calorique employé &
moins de refroidissement; ce qui cadre parfaitement avec le
résultat des expériences.
Un autre genre d'expérience prouve encore d'une manière aussi
évidente que l'état aériforme est une modification des corps &
qu'elle dépend du degré de température & de pression qu'ils
éprouvent.
Nous avons fait voir, M. de la Place & moi, dans un Mémoire que
nous avons lu à l'Académie en 1777, mais qui n'a pas été imprimé,
que lorsque l'éther étoit soumis à une pression de 28 pouces de
mercure, c'est-à-dire, à une pression égale à celle de l'atmosphère,
il entroit en ébullition à 32 ou 33 degrés du thermomètre de
mercure. M. de Luc, qui a fait des recherches analogues sur l'esprit-
de-vin, a reconnu qu'il entroit en ébullition à 67 degrés. Enfin, tout
le monde sait que l'eau commence à bouillir à 80 degrés.
L'ébullition n'étant autre chose que la vaporisation d'un fluide, ou le
moment de son passage de l'état liquide à celui d'un fluide
élastique aériforme, il étoit évident qu'en tenant constamment de
l'éther à une température supérieure à 33 degrés & au degré
habituel de pression de l'atmosphère, on devoit l'obtenir dans l'état
d'un fluide aériforme; que la même chose devoit arriver à l'esprit-
de-vin au-dessus de 67 degrés, & à l'eau au-dessus de 80, c'est ce
qui s'est trouvé parfaitement confirmé par les expériences
suivantes[3].
J'ai rempli avec de l'eau à 35 ou 36 degrés du thermomètre un
grand vase ABCD, planche VII, figure 15; je le suppose transparent
pour mieux faire sentir ce qui se passe dans son intérieur; on peut
encore tenir les mains assez long-temps dans de l'eau à ce degré
sans s'incommoder. J'y ai plongé des bouteilles à gouleau renversé
F, G, qui s'y sont emplies, après quoi je les ai retournées de
manière qu'elles eussent leur gouleau en en-bas, & appliqué contre
le fond du vase.
Les choses étant ainsi disposées, j'ai introduit de l'éther
sulfurique dans un très-petit matras, dont le col abc étoit
doublement recourbé; j'ai plongé ce matras dans l'eau du vase
ABCD, & j'ai engagé, comme on le voit représenté dans la figure
15, l'extrêmité de son col abc, dans le gouleau d'une des bouteilles
F: dès que l'éther a commencé à ressentir l'impression de la
chaleur, il est entré en ébullition; & le calorique qui s'est combiné
avec lui, l'a transformé en un fluide élastique aériforme, dont j'ai
rempli successivement plusieurs bouteilles F, G.
Ce n'est point ici le lieu d'examiner la nature & les propriétés de
ce fluide aériforme, qui est très-inflammable; mais sans anticiper
sur des connoissances que je ne dois pas supposer au lecteur,
j'observerai, en me fixant sur l'objet qui nous occupe dans ce
moment, que l'éther, d'après cette expérience, est tout près de ne
pouvoir exister dans la planette que nous habitons que dans l'état
aériforme; que si la pesanteur de notre atmosphère n'équivaloit
qu'à une colonne de 20 ou 24 pouces de mercure au lieu de 28,
nous ne pourrions obtenir l'éther dans l'état liquide, au moins
pendant l'été; que la formation de l'éther seroit par conséquent
impossible sur les montagnes un peu élevées, & qu'il se convertiroit
en gaz à mesure qu'il seroit formé, à moins qu'on n'employât des
ballons très-forts pour le condenser & qu'on ne joignît le
refroidissement à la pression. Enfin, que le degré de la chaleur du
sang étant à peu près celui où l'éther passe de l'état liquide à l'état
aériforme, il doit se vaporiser dans les premières voies, & qu'il est
très-vraisemblable que les propriétés de ce médicament tiennent à
cet effet, pour ainsi dire, mécanique.
Ces expériences réussissent encore mieux avec l'éther nitreux,
parce qu'il se vaporise à un degré de chaleur moindre que l'éther
sulfurique. A l'égard de l'alkool ou esprit-de-vin, l'expérience pour
l'obtenir dans l'état aériforme, présente un peu plus de difficulté,
parce que ce fluide n'étant susceptible de se vaporiser qu'à 67
degrés du thermomètre de Réaumur, il faut que l'eau du bain soit
entretenue presque bouillante, & qu'à ce degré il n'est plus possible
d'y plonger les mains.
Il étoit évident que la même chose devoit arriver à l'eau; que ce
fluide devoit également se transformer en gaz en l'exposant à un
degré de chaleur supérieur à celui qui le fait bouillir; mais quoique
convaincus de cette vérité, nous avons cru cependant, M. de la
Place & moi, devoir la confirmer par une expérience directe, & en
voici le résultat. Nous avons rempli de mercure une jarre de verre
A, planche VII, figure 5, dont l'ouverture étoit retournée en en-bas,
& nous avons passé dessous une soucoupe B, également remplie
de mercure. Nous avons introduit dans cette jarre environ deux
gros d'eau, qui ont gagné le haut CD de la jarre, & qui se sont
rangés au-dessus de la surface du mercure; puis nous avons
plongé le tout dans une grande chaudière de fer EFGH, placée sur
un fourneau GHIK: cette chaudière étoit remplie d'eau salée en
ébullition, dont la température excédoit 85 degrés du thermomètre;
on sait, en effet, que l'eau chargée de sels est susceptible de
prendre un degré de chaleur supérieur de plusieurs degrés à celui
de l'eau bouillante. Dès que les 2 gros d'eau, placés dans la partie
supérieure CD de la jarre ou tube, ont eu atteint la température de
80 degrés ou environ, ils sont entrés en ébullition, & au lieu
d'occuper, comme ils le faisoient, le petit espace ACD, ils se sont
convertis en un fluide aériforme, qui l'a remplie toute entière: le
mercure est même descendu un peu au-dessous de son niveau, &
la jarre auroit été renversée si elle n'avoit été très-épaisse, par
conséquent fort pesante, & si elle n'avoit d'ailleurs été assujettie à
la soucoupe par du fil de fer. Si-tôt qu'on retiroit la jarre du bain
d'eau salée, l'eau se condensoit & le mercure remontoit; mais elle
reprenoit l'état aériforme quelques instans après que l'appareil
avoit été replongé.
Voilà donc un certain nombre de substances qui se transforment
en fluides aériformes à des degrés de chaleur très-voisins de ceux
dans lesquels nous vivons. Nous verrons bientôt qu'il en est
d'autres, tels que l'acide marin ou muriatique, l'alkali volatil ou
ammoniaque, l'acide carbonique ou air fixe, l'acide sulfureux, &c.
qui demeurent constamment dans l'état aériforme, au degré
habituel de chaleur & de pression de l'atmosphère.
Tous ces faits particuliers, dont il me seroit facile de multiplier
les exemples, m'autorisent à faire un principe général de ce que j'ai
déjà annoncé plus haut, que presque tous les corps de la Nature
sont susceptibles d'exister dans trois états différens; dans l'état de
solidité, dans l'état de liquidité, & dans l'état aériforme, & que ces
trois états d'un même corps dépendent de la quantité de calorique
qui lui est combinée. Je désignerai dorénavant ces fluides
aériformes sous le nom générique de gaz; & je dirai en
conséquence que, dans toute espèce de gaz, on doit distinguer le
calorique, qui fait en quelque façon l'office de dissolvant, & la
substance qui est combinée avec lui & qui forme sa base.
C'est à ces bases des différens gaz qui sont encore peu
connues, que nous avons été obligés de donner des noms. Je les
indiquerai dans le Chapitre IV de cet Ouvrage, après que j'aurai
rendu compte de quelques phénomènes qui accompagnent
l'échauffement & le refroidissement des corps, & que j'aurai donné
des idées plus précises sur la constitution de notre atmosphère.
Nous avons vu que les molécules de tous les corps de la Nature
étoient dans un état d'équilibre entre l'attraction, qui tend à les
rapprocher & à les réunir, & les efforts du calorique qui tend à les
écarter. Ainsi non-seulement le calorique environne de toutes parts
les corps, mais encore il remplit les intervalles que leurs molécules
laissent entr'elles. On se formera une idée de ces dispositions, si
l'on se figure un vase rempli de petites balles de plomb & dans
lequel on verse une substance en poudre très-fine, telle que du
sablon: on conçoit que cette substance se répandra uniformément
dans les intervalles que les balles laissent entr'elles & les remplira.
Les balles, dans cet exemple, sont au sablon ce que les molécules
des corps sont au calorique; avec cette différence que, dans
l'exemple cité, les balles se touchent, au lieu que les molécules des
corps ne se touchent pas, & qu'elles sont toujours maintenues à
une petite distance les unes des autres par l'effort du calorique.
Si à des balles dont la figure est ronde, on substituoit des
hexaèdres, des octaèdres, ou des corps d'une figure régulière
quelconque & d'une égale solidité, la capacité des vuides qu'ils
laisseroient entr'eux ne seroit plus la même & l'on ne pourroit plus
y loger une aussi grande quantité de sablon. La même chose arrive
à l'égard de tous les corps de la Nature; les intervalles que leurs
molécules laissent entr'elles ne sont pas tous d'une égale capacité:
cette capacité dépend de la figure de ces molécules, de leur
grosseur, & de la distance les unes des autres à laquelle elles sont
maintenues, suivant le rapport qui existe entre leur force
d'attraction, & la force répulsive qu'exerce le calorique.
C'est dans ce sens qu'on doit entendre cette expression:
capacité des corps pour contenir la matière de la chaleur;
expression fort juste, introduite par les Physiciens Anglois, qui ont
eu les premiers des notions exactes à cet égard. Un exemple de ce
qui se passe dans l'eau & quelques réflexions sur la manière dont
ce fluide mouille & pénètre les corps, rendra ceci plus intelligible:
on ne sauroit trop s'aider dans les choses abstraites de
comparaisons sensibles.
Si l'on plonge dans l'eau des morceaux de différens bois, égaux
en volume, d'un pied cube, par exemple; ce fluide s'introduira peu
à peu dans leurs pores; ils se gonfleront & augmenteront de poids:
mais chaque espèce de bois admettra dans ses pores une quantité
d'eau différente; les plus légers & les plus poreux en logeront
davantage; ceux qui seront compactes & serrés, n'en laisseront
pénétrer qu'une très-petite quantité: enfin, la proportion d'eau
qu'ils recevront dépendra encore de la nature des molécules
constituantes du bois, de l'affinité plus ou moins grande qu'elles
auront avec l'eau, & les bois très-résineux, par exemple, quoique
très-poreux, en admettront très-peu. On pourra donc dire que les
différentes espèces de bois ont une capacité différente pour
recevoir de l'eau; on pourra même connoître, par l'augmentation de
poids, la quantité qu'ils en auront absorbée; mais comme on
ignorera la quantité d'eau qu'ils contenoient avant leur immersion,
il ne sera pas possible de connoître la quantité absolue qu'ils en
contiendront en en sortant.
Les mêmes circonstances ont lieu à l'égard des corps qui sont
plongés dans le calorique; en observant cependant que l'eau est un
fluide incompressible, tandis que le calorique est doué d'une grande
élasticité, ce qui signifie en d'autres termes que les molécules du
calorique ont une grande tendance à s'écarter les unes des autres,
quand une force quelconque les a obligées de se rapprocher, & l'on
conçoit que cette circonstance doit apporter des changemens très-
notables dans les résultats.
Les choses amenées à ce point de clarté & de simplicité, il me
sera aisé de faire entendre quelles sont les idées qu'on doit
attacher à ces expressions; calorique libre, & calorique combiné,
quantité spécifique de calorique contenue dans les différens corps,
capacité pour contenir le calorique, chaleur latente, chaleur
sensible, toutes expressions qui ne sont point synonimes; mais qui,
d'après ce que je viens d'exposer, ont un sens strict & déterminé.
C'est ce sens que je vais chercher encore à fixer par quelques
définitions.
Le calorique libre est celui qui n'est engagé dans aucune
combinaison. Comme nous vivons au milieu d'un systême de corps
avec lesquels le calorique a de l'adhérence, il en résulte que nous
n'obtenons jamais ce principe dans l'état de liberté absolue.
Le calorique combiné est celui qui est enchaîné dans les corps
par la force d'affinité ou d'attraction, & qui constitue une partie de
leur substance, même de leur solidité.
On entend par cette expression calorique spécifique des corps,
la quantité de calorique respectivement nécessaire pour élever d'un
même nombre de degrés la température de plusieurs corps égaux
en poids. Cette quantité de calorique dépend de la distance des
molécules des corps, de leur adhérence plus ou moins grande; &
c'est cette distance, ou plutôt l'espace qui en résulte, qu'on a
nommé, comme je l'ai déjà observé, capacité pour contenir le
calorique.
La chaleur, considérée comme sensation, ou en d'autres termes,
la chaleur sensible, n'est que l'effet produit sur nos organes par le
passage du calorique qui se dégage des corps environnans. En
général nous n'éprouvons de sensation que par un mouvement
quelconque, & l'on pourroit poser comme un axiome, point de
mouvement, point de sensation. Ce principe général s'applique
naturellement au sentiment du froid & du chaud: lorsque nous
touchons un corps froid, le calorique qui tend à se mettre en
équilibre dans tous les corps, passe de notre main dans le corps
que nous touchons, & nous éprouvons la sensation du froid. L'effet
contraire arrive lorsque nous touchons un corps chaud; le calorique
passe du corps à notre main, & nous avons la sensation de la
chaleur. Si le corps & la main sont du même degré de température,
ou à peu près, nous n'éprouvons aucune sensation, ni de froid, ni
de chaud, parce qu'alors il n'y a point de mouvement, point de
transport de calorique, & qu'encore une fois il n'y a pas de
sensation sans un mouvement qui l'occasionne.
Lorsque le thermomètre monte, c'est une preuve qu'il y a du
calorique libre qui se répand dans les corps environnans: le
thermomètre, qui est au nombre de ces corps, en reçoit sa part, en
raison de sa masse, & de la capacité qu'il a lui-même pour contenir
le calorique. Le changement qui arrive dans le thermomètre,
n'annonce donc qu'un déplacement de calorique, qu'un
changement arrivé à un systême de corps dont il fait partie; il
n'indique tout au plus que la portion de calorique qu'il a reçue,
mais il ne mesure pas la quantité totale qui a été dégagée,
déplacée ou absorbée. Le moyen le plus simple & le plus exact pour
remplir ce dernier objet est celui imaginé par M. de la Place, & qui
est décrit dans les Mémoires de l'Académie, année 1780, page 364.
On en trouve aussi une explication sommaire à la fin de cet
Ouvrage. Il consiste à placer le corps, ou la combinaison d'où se
dégage le calorique, au milieu d'une sphère creuse de glace: la
quantité de glace fondue est une expression exacte de la quantité
de calorique qui s'est dégagée. On peut, à l'aide de l'appareil que
nous avons fait construire d'après cette idée, connoître, non pas
comme on l'a prétendu, la capacité qu'ont les corps pour contenir
le calorique, mais le rapport des augmentations ou diminutions que
reçoivent ces capacités, par des nombres déterminés de degrés du
thermomètre. Il est facile, avec le même appareil, & par diverses
combinaisons d'expériences, de connoître la quantité de calorique
nécessaire pour convertir les corps solides en liquides & ceux-ci en
fluides aériformes, & réciproquement, ce que les fluides élastiques
abandonnent de calorique quand ils redeviennent liquides, & ceux-
ci quand ils redeviennent solides. On pourra donc parvenir un jour,
lorsque les expériences auront été assez multipliées, à déterminer
le rapport de calorique qui constitue chaque espèce de gaz. Je
rendrai compte, dans un Chapitre particulier, des principaux
résultats que nous avons obtenus en ce genre.
Il me reste, en finissant cet article, à dire un mot sur la cause
de l'élasticité des gaz & des fluides en vapeurs. Il n'est pas difficile
d'appercevoir que cette élasticité tient à celle du calorique, qui
paroît être le corps éminemment élastique de la nature. Rien de
plus simple que de concevoir qu'un corps devient élastique en se
combinant avec un autre qui est lui-même doué de cette propriété.
Mais il faut convenir que c'est expliquer l'élasticité par l'élasticité;
qu'on ne fait par-là que reculer la difficulté, & qu'il reste toujours à
expliquer ce que c'est que l'élasticité, & pourquoi le calorique est
élastique. En considérant l'élasticité dans un sens abstrait, elle n'est
autre chose que la propriété qu'ont les molécules d'un corps de
s'éloigner les unes des autres, lorsqu'on les a forcées de
s'approcher. Cette tendance qu'ont les molécules du calorique à
s'écarter, a lieu même à de fort grandes distances. On en sera
convaincu si l'on considère que l'air est susceptible d'un grand
degré de compression; ce qui suppose que ses molécules sont déjà
très-éloignées les unes des autres: car la possibilité de se
rapprocher, suppose une distance au moins égale à la quantité du
rapprochement. Or ces molécules de l'air qui sont déjà très-
éloignées entr'elles tendent encore à s'éloigner davantage: en effet,
si on fait le vuide de Boyle dans un très-vaste récipient, les
dernières portions d'air qui y restent se répandent uniformément
dans toute la capacité du vase, quelque grand qu'il soit, elles le
remplissent en entier & pressent contre ses parois: or cet effet ne
peut s'expliquer qu'en supposant que les molécules font un effort
en tout sens pour s'écarter, & l'on ne connoît point la distance à
laquelle ce phénomène s'arrête.
Il y a donc une véritable répulsion entre les molécules des
fluides élastiques; ou du moins les choses se passent de la même
manière que si cette répulsion avoit lieu, & on auroit quelque droit
d'en conclure que les molécules du calorique se repoussent les
unes les autres. Cette force de répulsion une fois admise, les
explications relatives à la formation des fluides aériformes ou gaz
deviendroient fort simples: mais il faut convenir en même temps
qu'une force répulsive, entre des molécules très-petites, qui agit à
de grandes distances est difficile à concevoir.
Il paroîtroit peut-être plus naturel de supposer que les
molécules du calorique s'attirent plus entr'elles que ne le font les
molécules des corps, & qu'elles ne les écartent que pour obéir à la
force d'attraction qui les oblige de se réunir. Il se passe quelque
chose d'analogue à ce phénomène, quand on plonge une éponge
sèche dans de l'eau: elle se gonfle; ses molécules s'écartent les
unes des autres, & l'eau remplit tous les intervalles. Il est clair que
cette éponge en se gonflant a acquis plus de capacité pour contenir
de l'eau, qu'elle n'en avoit auparavant. Mais peut-on dire que
l'introduction de l'eau entre ses molécules leur ait communiqué une
force répulsive qui tende à les écarter les unes des autres? Non,
sans doute: il n'y a au contraire que des forces attractives qui
agissent dans ce cas, & ces forces sont, 1o. la pesanteur de l'eau &
l'action qu'elle exerce en tout sens, comme tous les fluides; 2o. la
force attractive des molécules de l'eau les unes à l'égard des
autres; 3o. la force attractive des molécules de l'éponge entr'elles;
enfin, l'attraction réciproque des molécules de l'eau & de celles de
l'éponge. Il est aisé de concevoir que c'est de l'intensité & du
rapport de toutes ces forces, que dépend l'explication du
phénomène. Il est probable que l'écartement des molécules des
corps par le calorique, tient de même à une combinaison de
différentes forces attractives, & c'est le résultat de ces forces que
nous cherchons à exprimer d'une manière plus concise & plus
conforme à l'état d'imperfection de nos connoissances, lorsque
nous disons que le calorique communique une force répulsive aux
molécules des corps.
CHAPITRE II.

Vues générales sur la formation & la constitution de l'atmosphère


de la terre.

L es considérations que je viens de présenter sur la formation des


fluides élastiques aériformes ou gaz, jettent un grand jour sur la
manière dont se sont formées, dans l'origine des choses, les
atmosphères des planètes, & notamment celle de la terre. On
conçoit que cette dernière doit être le résultat & le mélange 1o. de
toutes les substances susceptibles de se vaporiser ou plutôt de
rester dans l'état aériforme, au degré de température dans lequel
nous vivons, & à une pression égale au poids d'une colonne de
mercure de 28 pouces de hauteur; 2o. de toutes les substances
fluides ou concrètes susceptibles de se dissoudre dans cet
assemblage de différens gaz.
Pour mieux fixer nos idées relativement à cette matière sur
laquelle on n'a point encore assez réfléchi, considérons un moment
ce qui arriveroit aux différentes substances qui composent le globe,
si la température en étoit brusquement changée. Supposons, par
exemple, que la terre se trouvât transportée tout à coup dans une
région beaucoup plus chaude du systême solaire; dans la région de
mercure, par exemple, où la chaleur habituelle est probablement
fort supérieure à celle de l'eau bouillante: bientôt l'eau, tous les
fluides susceptibles de se vaporiser à des degrés voisins de l'eau
bouillante, & le mercure lui-même, entreroient en expansion; ils se
transformeroient en fluides aériformes ou gaz, qui deviendroient
parties de l'atmosphère. Ces nouvelles espèces d'air se mêleroient
avec celles déjà existantes, & il en résulteroit des décompositions
réciproques, des combinaisons nouvelles, jusqu'à ce que les
différentes affinités se trouvant satisfaites, les principes qui
composeroient ces différens airs ou gaz, arrivassent à un état de
repos. Mais une considération qui ne doit pas échapper, c'est que
cette vaporisation même auroit des bornes: en effet à mesure que
la quantité des fluides élastiques augmenteroit, la pesanteur de
l'atmosphère s'accroîtroit en proportion: or, puisqu'une pression
quelconque est un obstacle à la vaporisation, puisque les fluides les
plus évaporables peuvent résister, sans se vaporiser, à une chaleur
très-forte, quand on y oppose une pression proportionnellement
plus forte encore; enfin, puisque l'eau elle-même & tous les
liquides, peuvent éprouver dans la machine de Papin, une chaleur
capable de les faire rougir, on conçoit que la nouvelle atmosphère
arriveroit à un degré de pesanteur tel, que l'eau qui n'auroit pas été
vaporisée jusqu'alors, cesseroit de bouillir, & resteroit dans l'état de
liquidité; en sorte que même dans cette supposition, comme dans
toute autre de même genre, la pesanteur de l'atmosphère seroit
limitée & ne pourroit pas excéder un certain terme. On pourroit
porter ces réflexions beaucoup plus loin, & examiner ce qui
arriveroit aux pierres, aux sels, & à la plus grande partie des
substances fusibles qui composent le globe: on conçoit qu'elles se
ramolliroient, qu'elles entreroient en fusion & formeroient des
fluides; mais ces dernières considérations sortent de mon objet, &
je me hâte d'y rentrer.
Par un effet contraire, si la terre se trouvoit tout à coup placée
dans des régions très-froides, l'eau qui forme aujourd'hui nos
fleuves & nos mers, & probablement le plus grand nombre des
fluides que nous connoissons, se transformeroit en montagnes
solides, en rochers très-durs, d'abord diaphanes, homogènes &
blancs comme le cristal de roche; mais qui, avec le temps, se
mêlant avec des substances de différente nature, deviendroient des
pierres opaques diversement colorées.
L'air, dans cette supposition, ou au moins une partie des
substances aériformes qui le composent, cesseroient sans doute
d'exister dans l'état de vapeurs élastiques, faute d'un degré de
chaleur suffisant; elles reviendroient donc à l'état de liquidité, & il
en résulteroit de nouveaux liquides dont nous n'avons aucune idée.

Ces deux suppositions extrêmes font voir clairement 1o. que


solidité, liquidité, élasticité, sont trois états différens de la même
matière, trois modifications particulières, par lesquelles presque
toutes les substances peuvent successivement passer, & qui
dépendent uniquement du degré de chaleur auquel elles sont
exposées, c'est-à-dire, de la quantité de calorique dont elles sont
pénétrées; 2o. qu'il est très-probable que l'air est un fluide
naturellement en vapeurs, ou pour mieux dire, que notre
atmosphère est un composé de tous les fluides susceptibles
d'exister dans un état de vapeurs & d'élasticité constante, au degré
habituel de chaleur & de pression que nous éprouvons; 3o. qu'il ne
seroit pas par conséquent impossible qu'il se rencontrât dans notre
atmosphère des substances extrêmement compactes, des métaux
même, & qu'une substance métallique, par exemple, qui seroit un
peu plus volatile que le mercure, seroit dans ce cas.
On sait que parmi les fluides que nous connoissons, les uns,
comme l'eau & l'alkool ou esprit-de-vin, sont susceptibles de se
mêler les uns avec les autres dans toutes proportions: les autres,
au contraire, comme le mercure, l'eau & l'huile, ne peuvent
contracter que des adhérences momentanées, ils se séparent les
uns des autres lorsqu'ils ont été mêlangés, & se rangent en raison
de leur gravité spécifique. La même chose doit, ou au moins peut
arriver dans l'atmosphère: il est possible, il est même probable qu'il
s'est formé dans l'origine & qu'il se forme tous les jours des gaz qui
ne sont que difficilement miscibles à l'air de l'atmosphère & qui s'en
séparent; si ces gaz sont plus légers, ils doivent se rassembler dans
les régions élevées, & y former des couches qui nagent sur l'air
atmosphérique. Les phénomènes qui accompagnent les météores
ignés me portent à croire qu'il existe ainsi dans le haut de
l'atmosphère une couche d'un fluide inflammable, & que c'est au
point de contact de ces deux couches d'air que s'opèrent les
phénomènes de l'aurore boréale & des autres météores ignés. Je
me propose de développer mes idées à cet égard dans un Mémoire
particulier.
CHAPITRE III.

Analyse de l'air de l'atmosphère: sa résolution en deux fluides


élastiques, l'un respirable, l'autre non-respirable.

T est donc à priori la constitution de notre atmosphère; elle


elle
doit être formée de la réunion de toutes les substances
susceptibles de demeurer dans l'état aériforme au degré habituel
de température & de pression que nous éprouvons. Ces fluides
forment une masse de nature à peu près homogène, depuis la
surface de la terre jusqu'à la plus grande hauteur à laquelle on soit
encore parvenu, & dont la densité décroît en raison inverse des
poids dont elle est chargée; mais comme je l'ai dit, il est possible
que cette première couche soit recouverte d'une ou de plusieurs
autres de fluides très-différens.
Il nous reste maintenant à déterminer quel est le nombre &
quelle est la nature des fluides élastiques qui composent cette
couche inférieure que nous habitons; & c'est sur quoi l'expérience
va nous éclairer. La Chimie moderne a fait à cet égard un grand
pas; & les détails dans lesquels je vais entrer feront connoître que
l'air de l'atmosphère est peut-être de toutes les substances de cet
ordre, celle dont l'analyse est la plus exactement & la plus
rigoureusement faite.
La Chimie présente en général deux moyens pour déterminer la
nature des parties constituantes d'un corps, la composition & la
décomposition. Lors, par exemple, que l'on a combiné ensemble de
l'eau & de l'esprit-de-vin ou alkool, & que par le résultat de ce
mêlange on a formé l'espèce de liqueur qui porte le nom d'eau-de-
vie dans le commerce, on a droit d'en conclure que l'eau-de-vie est
un composé d'alkool & d'eau: mais on peut arriver à la même
conclusion par voie de décomposition, & en général on ne doit être
pleinement satisfait en Chimie qu'autant qu'on a pu réunir ces deux
genres de preuves.
On a cet avantage dans l'analyse de l'air de l'atmosphère; on
peut le décomposer & le recomposer; & je me bornerai à rapporter
ici les expériences les plus concluantes qui aient été faites à cet
égard. Il n'en est presque aucunes qui ne me soient devenues
propres, soit parce que je les ai faites le premier, soit parce que je
les ai répétées sous un point de vue nouveau, sous celui d'analyser
l'air de l'atmosphère.
J'ai pris, planche II, figure 14, un matras A de 36 pouces
cubiques environ de capacité dont le col BCDE étoit très-long, &
avoit six à sept lignes de grosseur intérieurement. Je l'ai courbé,
comme on le voit représenté, planche IV, figure 2, de manière qu'il
pût être placé dans un fourneau MMNN, tandis que l'extrêmité E de
son col iroit s'engager sous la cloche FG, placée dans un bain de
mercure RRSS. J'ai introduit dans ce matras quatre onces de
mercure très-pur, puis en suçant avec un siphon que j'ai introduit
sous la cloche FG, j'ai élevé le mercure jusqu'en LL: j'ai marqué
soigneusement cette hauteur avec une bande de papier collé, & j'ai
observé exactement le baromètre & le thermomètre.
Les choses ainsi préparées, j'ai allumé du feu dans le fourneau
MMNN, & je l'ai entretenu presque continuellement pendant douze
jours, de manière que le mercure fut échauffé presqu'au degré
nécessaire pour le faire bouillir.
Il ne s'est rien passé de remarquable pendant tout le premier
jour: le mercure quoique non bouillant, étoit dans un état
d'évaporation continuelle; il tapissoit l'intérieur des vaisseaux de
goutelettes, d'abord très-fines, qui alloient ensuite en augmentant,
& qui, lorsqu'elles avoient acquis un certain volume, retomboient
d'elles-mêmes au fond du vase, & se réunissoient au reste du
mercure. Le second jour, j'ai commencé à voir nager sur la surface
du mercure de petites parcelles rouges, qui, pendant quatre ou
cinq jours ont augmenté en nombre & en volume, après quoi elles
ont cessé de grossir & sont restées absolument dans le même état.
Au bout de douze jours voyant que la calcination du mercure ne
faisoit plus aucun progrès, j'ai éteint le feu & j'ai laissé refroidir les
vaisseaux. Le volume de l'air contenu tant dans le matras que dans
son col & sous la partie vuide de la cloche, réduit à une pression de
28 pouces & à 10 degrés du thermomètre, étoit avant l'opération
de 50 pouces cubiques environ. Lorsque l'opération a été finie, ce
même volume à pression & à température égale, ne s'est plus
trouvé que de 42 à 43 pouces: il y avoit eu par conséquent une
diminution de volume d'un sixième environ. D'un autre côté ayant
rassemblé soigneusement les parcelles rouges qui s'étoient
formées, & les ayant séparées autant qu'il étoit possible du
mercure coulant dont elles étoient baignées, leur poids s'est trouvé
de 45 grains.
J'ai été obligé de répéter plusieurs fois cette calcination du
mercure en vaisseaux clos, parce qu'il est difficile, dans une seule &
même expérience, de conserver l'air dans lequel on a opéré, & les
molécules rouges ou chaux de mercure qui s'est formé. Il
m'arrivera souvent de confondre ainsi, dans un même récit, le
résultat de deux ou trois expériences de même genre.
L'air qui restoit après cette opération & qui avoit été réduit aux
cinq sixièmes de son volume, par la calcination du mercure, n'étoit
plus propre à la respiration ni à la combustion; car les animaux
qu'on y introduisoit y périssoient en peu d'instans, & les lumières
s'y éteignoient sur le champ, comme si on les eût plongées dans de
l'eau.
D'un autre côté, j'ai pris les 45 grains de matière rouge qui
s'étoit formée pendant l'opération; je les ai introduits dans une
très-petite cornue de verre à laquelle étoit adapté un appareil
propre à recevoir les produits liquides & aériformes qui pourroient
se séparer: ayant allumé du feu dans le fourneau, j'ai observé qu'à
mesure que la matière rouge étoit échauffée sa couleur augmentoit
d'intensité. Lorsqu'ensuite la cornue a approché de l'incandescence,
la matière rouge a commencé à perdre peu à peu de son volume, &
en quelques minutes elle a entièrement disparu; en même temps il
s'est condensé dans le petit récipient 41 grains 1/2 de mercure
coulant, & il a passé sous la cloche 7 à 8 pouces cubiques d'un
fluide élastique beaucoup plus propre que l'air de l'atmosphère à
entretenir la combustion & la respiration des animaux.
Ayant fait passer une portion de cet air dans un tube de verre
d'un pouce de diamètre & y ayant plongé une bougie, elle y
répandoit un éclat éblouissant; le charbon au lieu de s'y
consommer paisiblement comme dans l'air ordinaire, y brûloit avec
flamme & une sorte de décrépitation, à la manière du phosphore, &
avec une vivacité de lumière que les yeux avoient peine à
supporter. Cet air que nous avons découvert presque en même
temps, M. Priestley, M. Schéele & moi, a été nommé par le premier,
air déphlogistiqué; par le second, air empiréal. Je lui avois d'abord
donné le nom d'air éminemment respirable: depuis, on y a
substitué celui d'air vital. Nous verrons bientôt ce qu'on doit penser
de ces dénominations.
En réfléchissant sur les circonstances de cette expérience, on
voit que le mercure en se calcinant absorbe la partie salubre &
respirable de l'air, ou, pour parler d'une manière plus rigoureuse, la
base de cette partie respirable; que la portion d'air qui reste est
une espèce de mofète, incapable d'entretenir la combustion & la
respiration: l'air de l'atmosphère est donc composé de deux fluides
élastiques de nature différente & pour ainsi dire opposée.
Une preuve de cette importante vérité, c'est qu'en recombinant
les deux fluides élastiques qu'on a ainsi obtenus séparément, c'est-
à-dire, les 42 pouces cubiques de mofète, ou air non respirable, &
les 8 pouces cubiques d'air respirable, on reforme de l'air, en tout
semblable à celui de l'atmosphère, & qui est propre à peu près au
même degré, à la combustion, à la calcination des métaux, & à la
respiration des animaux.
Quoique cette expérience fournisse un moyen infiniment simple
d'obtenir séparément les deux principaux fluides élastiques qui
entrent dans la composition de notre atmosphère, elle ne nous
donne pas des idées exactes sur la proportion de ces deux fluides.
L'affinité du mercure pour la partie respirable de l'air, ou plutôt pour
sa base, n'est pas assez grande pour qu'elle puisse vaincre
entièrement les obstacles qui s'opposent à cette combinaison. Ces
obstacles sont l'adhérence des deux fluides constitutifs de l'air de
l'atmosphère & la force d'affinité qui unit la base de l'air vital au
calorique: en conséquence la calcination du mercure finie, ou au
moins portée aussi loin qu'elle peut l'être, dans une quantité d'air
déterminée, il reste encore un peu d'air respirable combiné avec la
mofète, & le mercure ne peut en séparer cette dernière portion. Je
ferai voir dans la suite que la proportion d'air respirable & d'air non
respirable qui entre dans la composition de l'air atmosphérique est
dans le rapport de 27 à 73, au moins dans les climats que nous
habitons: je discuterai en même temps les causes d'incertitude qui
existent encore sur l'exactitude de cette proportion.
Puisqu'il y a décomposition de l'air dans la calcination du
mercure, puisqu'il y a fixation & combinaison de la base de la partie
respirable avec le mercure, il résulte des principes que j'ai
précédemment exposés, qu'il doit y avoir dégagement de calorique
& de lumière; & l'on ne sauroit douter que ce dégagement n'ait lieu
en effet: mais deux causes empêchent qu'il ne soit rendu sensible
dans l'expérience dont je viens de rendre compte. La première,
parce que la calcination durant pendant plusieurs jours, le
dégagement de chaleur & de lumière, réparti sur un aussi long
intervalle de temps, est infiniment foible pour chaque instant en
particulier: la seconde, parce que l'opération se faisant dans un
fourneau & à l'aide du feu, la chaleur occasionnée par la calcination
se confond avec celle du fourneau. Je pourrois ajouter que la partie
respirable de l'air, ou plutôt sa base, en se combinant avec le
mercure, n'abandonne pas la totalité du calorique qui lui étoit uni,
qu'une partie demeure engagée dans la nouvelle combinaison;
mais cette discussion & les preuves que je serois obligé de
rapporter, ne seroient pas à leur place ici.
Il est au surplus aisé de rendre sensible le dégagement de la
chaleur & de la lumière en opérant d'une manière plus prompte la
décomposition de l'air. Le fer, qui a beaucoup plus d'affinité que le
mercure avec la base de la partie respirable de l'air, en fournit un
moyen. Tout le monde connoît aujourd'hui la belle expérience de M.
Ingenhouz sur la combustion du fer. On prend un bout de fil de fer
très-fin BC, planche IV, figure 17, tourné en spirale, on fixe l'une de
ses extrêmités B, dans un bouchon de liége A, destiné à boucher la
bouteille DEFG. On attache à l'autre extrêmité de ce fil de fer, un
petit morceau d'amadoue C. Les choses ainsi disposées, on emplit
avec de l'air dépouillé de sa partie non respirable, la bouteille
DEFG. On allume l'amadoue C, puis on l'introduit promptement,
ainsi que le fil de fer BC dans la bouteille, & on la bouche comme
on le voit dans la figure que je viens de citer.
Aussi-tôt que l'amadoue est plongée dans l'air vital, elle
commence à brûler avec un éclat éblouissant; elle communique
l'inflammation au fer, qui brûle lui même en répandant de brillantes
étincelles, lesquelles tombent au fond de la bouteille, en globules
arrondis qui deviennent noirs en se refroidissant, & qui conservent
un reste de brillant métallique. Le fer ainsi brûlé, est plus cassant &
plus fragile, que ne le seroit le verre lui-même; il se réduit
facilement en poudre & est encore attirable à l'aimant, moins
cependant qu'il ne l'étoit avant sa combustion.
M. Ingenhouz n'a examiné ni ce qui arrivoit au fer, ni ce qui
arrivoit à l'air dans cette opération, en sorte que je me suis trouvé
obligé de la répéter avec des circonstances différentes & dans un
appareil plus propre à répondre à mes vues.
J'ai rempli une cloche A, planche IV, fig. 3, de six pintes environ
de capacité d'air pur, autrement dit, de la partie éminemment
respirable de l'air. J'ai transporté, à l'aide d'un vase très-plat, cette
cloche sur un bain de mercure contenu dans le bassin BC; après
quoi j'ai séché soigneusement avec du papier gris la surface du
mercure, tant dans l'intérieur qu'à l'extérieur de la cloche. Je me
suis muni, d'un autre côté, d'une petite capsule de porcelaine D,
plate & évasée, dans laquelle j'ai placé de petits coupeaux de fer
tournés en spirale, & que j'ai arrangés de la manière qui m'a paru
la plus favorable pour que la combustion se communiquât à toutes
les parties. A l'extrêmité d'un de ces coupeaux, j'ai attaché un petit
morceau d'amadoue, & j'y ai ajouté un fragment de phosphore, qui
pesoit à peine un seizième de grain. J'ai introduit la capsule sous la
cloche en soulevant un peu cette dernière. Je n'ignore pas que par
cette manière de procéder, il se mêle une petite portion d'air
commun avec l'air de la cloche; mais ce mêlange, qui est peu
considérable lorsqu'on opère avec adresse, ne nuit point au succès
de l'expérience.
Lorsque la capsule D est introduite sous la cloche, on succe une
partie de l'air qu'elle contient, afin d'élever le mercure dans son
intérieur jusqu'en EF; on se sert à cet effet d'un siphon GHI, qu'on
passe par-dessous, & pour qu'il ne se remplisse pas de mercure, on
tortille un petit morceau de papier à son extrêmité. Il y a un art
pour élever ainsi en suçant le mercure sous la cloche: si on se
contentoit d'aspirer l'air avec le poumon, on n'atteindroit qu'à une
très-médiocre élévation, par exemple, d'un pouce ou d'un pouce &
demi tout au plus, tandis que par l'action des muscles de la bouche
on élève, sans se fatiguer, ou au moins sans risquer de
s'incommoder, le mercure jusqu'à 6 à 7 pouces.
Après que tout a été ainsi préparé, on fait rougir au feu un fer
recourbé MN, planche IV, figure 16, destiné à ces sortes
d'expériences; on le passe par-dessous la cloche & avant qu'il ait eu
le temps de se refroidir, on l'approche du petit morceau de
phosphore contenu dans la capsule de porcelaine D: aussi-tôt le
phosphore s'allume, il communique son inflammation à l'amadoue,
& celle-ci la communique au fer. Quand les copeaux ont été bien
arrangés, tout le fer brûle jusqu'au dernier atôme, en répandant
une lumière blanche, brillante, & semblable à celle qu'on observe
dans les étoiles d'artifice Chinois. La grande chaleur qui s'opère
pendant cette combustion, liquéfie le fer, & il tombe en globules
ronds de grosseur différente, dont le plus grand nombre reste dans
la capsule, & dont quelques-uns sont lancés au dehors & nagent
sur la surface du mercure.
Dans le premier instant de la combustion il y a une légère
augmentation dans le volume de l'air, en raison de la dilatation
occasionnée par la chaleur: mais bientôt une diminution rapide
succède à la dilatation; le mercure remonte dans la cloche, &
lorsque la quantité de fer est suffisante, & que l'air avec lequel on
opère est bien pur, on parvient à l'absorber presqu'en entier.
Je dois avertir ici qu'à moins qu'on ne veuille faire des
expériences de recherches, il vaut mieux ne brûler que des
quantités médiocres de fer. Quand on veut pousser trop loin
l'expérience & absorber presque tout l'air, la capsule D qui nage sur
le mercure, se rapproche trop de la voûte de la cloche, & la grande
chaleur jointe au refroidissement subit, occasionné par le contact
du mercure, fait éclater le verre: le poids de la colonne de mercure
qui vient à tomber rapidement, dès qu'il s'est fait une félure à la
cloche, occasionne un flot qui fait jaillir une grande partie de ce
fluide hors du bassin. Pour éviter ces inconvéniens & être sûr du
succès de l'expérience, on ne doit guère brûler plus d'un gros &
demi de fer sous une cloche de huit pintes de capacité. Cette
cloche doit être forte, afin de résister au poids de mercure qu'elle
est destinée à contenir.
Il n'est pas possible de déterminer à la fois dans cette
expérience, le poids que le fer acquiert, & les changemens arrivés à
l'air. Si c'est l'augmentation de poids du fer & son rapport avec
l'absorption de l'air, dont on cherche à connoître la quantité, on doit
avoir soin de marquer très-exactement sur la cloche, avec un trait
de diamant, la hauteur du mercure avant & après l'expérience; on
passe ensuite sous la cloche le siphon GH, planche IV, figure 3,
garni d'un papier qui empêche qu'il ne s'emplisse de mercure. On
met le pouce sur l'extrêmité G, & on rend l'air peu à peu en
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.

More than just a book-buying platform, we strive to be a bridge


connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.

Join us on a journey of knowledge exploration, passion nurturing, and


personal growth every day!

ebookbell.com

You might also like