Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: Use glibc with LSE to improve the performance of workloads on Arm servers
title: Use glibc with Large System Extensions (LSE) to improve the performance of workloads on Arm servers

minutes_to_complete: 60

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# ================================================================================

next_step_guidance: >
You can continue learning about porting other cloud applications to the Arm architecture for increased performance and cost savings.
You can continue learning about Large System Extensions and how to use them in your applications.
# 1-3 sentence recommendation outlining how the reader can generally keep learning about these topics, and a specific explanation of why the next step is being recommended.

recommended_path: "/learning-paths/servers-and-cloud-computing/lse"
Expand All @@ -18,13 +18,13 @@ recommended_path: "/learning-paths/servers-and-cloud-computing/lse"

further_reading:
- resource:
title: Arm Architecture Reference Manual
link: https://developer.arm.com/documentation/ddi0487/latest
type: documentation
title: Arm's LSE for atomics and MySQL
link: https://mysqlonarm.github.io/ARM-LSE-and-MySQL/
type: blog
- resource:
title: Projects releated with MongoDB
link: https://github.com/mongodb
type: website
title: MongoDB documentation
link: https://www.mongodb.com/docs/
type: documentation

# ================================================================================
# FIXED, DO NOT MODIFY
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,26 @@ layout: "learningpathall"
---


## Before you begin
## Overview
"Glibc with LSE" refers to the version of [the GNU C Library (glibc)](https://www.gnu.org/software/libc/) that includes support for [LSE (Large Systems Extensions)](https://learn.arm.com/learning-paths/servers-and-cloud-computing/lse/). LSE is an extension to the ARMv8-A architecture that provides enhanced atomic operations and memory model features.

LSE introduces additional atomic instructions and operations, such as Load-Acquire, Store-Release, and Atomic Compare-and-Swap (CAS). These operations allow for more efficient synchronization and concurrent access to shared memory in multi-threaded applications running on ARMv8-A processors.

When glibc is compiled with LSE support, it can take advantage of these enhanced atomic operations provided by the LSE extension. This can potentially improve the performance of multi-threaded applications that heavily rely on atomic operations and synchronization primitives.

## Before you begin

Launch an [Arm based instance](/learning-paths/servers-and-cloud-computing/csp/) running Ubuntu version 20.04.

On your machine, install the dependencies required to build glibc:

```bash
sudo apt update
sudo apt install -y gcc-10 g++-10 gawk bison make
```

## Build and Install Glibc
You can build glibc without installing, or with installing to a specific directory.
You can now checkout the glibc source package and create a build directory:

```bash
cd ~
Expand All @@ -29,55 +39,33 @@ build=~/glibc-2.32_build_install/build
mkdir -p $build
cd $build
```
Before execute the command "./glibc/configure", gawk and bison should be installed.
Glibc-2.32 matches gcc-10 perfect, and the version of ld(GNU linker) should not be higher than 2.35.
__So Ubuntu 20.04 is strongly recommended!__
```
sudo apt update
sudo apt install -y gcc-10 g++-10 gawk bison make
```

- __Without installing__
```bash
sudo bash ~/glibc/configure --prefix=/usr --disable-werror CC=gcc-10 CXX=g++-10
sudo make -C $build -j$(expr $(nproc) - 1)
```
Configure glibc and run make to build it:

- __OR__
```bash
sudo bash ~/glibc/configure --prefix=/usr --disable-werror CC=gcc-10 CXX=g++-10
sudo make -C $build -j$(expr $(nproc) - 1)
```
You have now successfully built glibc from source without LSE.

- __With installing to a specific directory__
```bash
install=~/glibc-2.32_build_install/install
mkdir -p ${install}
sudo make -C $build -j$(expr $(nproc) - 1) install DESTDIR=${install}
sudo make -C $build -j$(expr $(nproc) - 1) localedata/install-locales DESTDIR=${install}
sudo make -C $build -j$(expr $(nproc) - 1) localedata/install-locale-files DESTDIR=${install}
```
Now lets look at how you can build it with LSE support.

## Build glibc With LSE
To build glibc with LSE, you should add `CFLAGS` and `CXXFLAGS` to the configure command.

## With LSE
If you want to build glibc with LSE, you should add `CFLAGS` and `CXXFLAGS` to configure implicitly or explicitly.
You can do this one of two ways. One way is to use "-mcpu=native" which tells the compiler to detect the architecture/micro-architecture of your machine. The other way is to pass the exact architecture option of your machine to the compiler using "-mcpu=neoverse-n2+lse"

Both ways to configure are shown below:

```bash
sudo bash ~/glibc/configure --prefix=/usr --disable-werror CC=gcc-10 CXX=g++-10 CFLAGS="-mcpu=native -O3" CXXFLAGS="-mcpu=native -O3"
sudo make -C $build -j$(expr $(nproc) - 1)
```
OR

```bash
sudo bash ~/glibc/configure --prefix=/usr --disable-werror CC=gcc-10 CXX=g++-10 CFLAGS="-mcpu=neoverse-n2+lse -O3" CXXFLAGS="-mcpu=neoverse-n2+lse -O3"
sudo make -C $build -j$(expr $(nproc) - 1)
```

##

## With NO-LSE

```bash
sudo bash ~/glibc/configure --prefix=/usr --disable-werror CC=gcc-10 CXX=g++-10
sudo make -C $build -j$(expr $(nproc) - 1)
```
OR
```bash
sudo bash ~/glibc/configure --prefix=/usr --disable-werror CC=gcc-10 CXX=g++-10 CFLAGS="-mcpu=neoverse-n2+nolse -O3" CXXFLAGS="-mcpu=neoverse-n2+nolse -O3"
sudo make -C $build -j$(expr $(nproc) - 1)
```
After running make, you should see glibc (libc.so.6) with LSE support in your build directory.
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ weight: 6 # 1 is first, 2 is second, etc.
layout: "learningpathall"
---

Now you can run the mongodb benchmark using Glibc with LSE and NoLSE and compare the results.
You can run the mongodb benchmark using Glibc with LSE and NoLSE and compare the results. This will give you an idea of the performance gained by using Glibc with LSE.

## Result with No-LSE
Launch MongoDB with Glibc without LSE and obtain benchmark result.
The overall TPS is __6662.1275371047195__ with No-LSE Glibc.
```console
The output will look similar to:

```output
[OVERALL], RunTime(ms), 750511
[OVERALL], Throughput(ops/sec), 6662.1275371047195
[TOTAL_GCS_G1_Young_Generation], Count, 3527
Expand Down Expand Up @@ -58,11 +59,13 @@ The overall TPS is __6662.1275371047195__ with No-LSE Glibc.
[SCAN], 99thPercentileLatency(us), 70143
[SCAN], Return=OK, 1499804
```
The overall throughtput (operations/sec) is 6662.1275371047195 with No-LSE Glibc.

## Result with LSE
Launch MongoDB with Glibc with LSE and obtain benchmark result.
The overall TPS is __6871.605426919102__ with LSE Glibc.
___So you can get around 3.14% extra benefit through Glibc with LSE!___
Launch MongoDB again, this time with Glibc with LSE and obtain benchmark result.

The output will look similar to:

```console
[OVERALL], RunTime(ms), 727632
[OVERALL], Throughput(ops/sec), 6871.605426919102
Expand Down Expand Up @@ -109,4 +112,7 @@ ___So you can get around 3.14% extra benefit through Glibc with LSE!___
[SCAN], 99thPercentileLatency(us), 67455
[SCAN], Return=OK, 1499682
```
The overall throughput (operations/sec) is 6871.605426919102 when using Glibc with LSE.
In this case you can get around 3.14% performance uplift by using Glibc with LSE.


Original file line number Diff line number Diff line change
Expand Up @@ -22,38 +22,45 @@ Overall, YCSB has become a standard benchmarking tool in the cloud and distribut
You are now ready to benchmark MongoDB with YCSB on your Arm server!

## YCSB Setup
Setup the YCSB on a benchmark machine with __JAVA__:
Install Java on your machine:

```console
sudo apt-get install -y openjdk-11-jdk
```
Download the uncompress the YCSB Benchmark source:

```console
cd ~
wget -c https://github.com/brianfrankcooper/YCSB/releases/download/0.17.0/ycsb-0.17.0.tar.gz
tar xfvz ycsb-0.17.0.tar.gz
```

Create a workload file with the following content:
Using a file editor of your choice, create a workload file `~/ycsb-0.17.0/workloads/iworkload`. Copy and save the following content into this file:

```
vi ~/ycsb-0.17.0/workloads/iworkload

recordcount=1000
operationcount=1000
workload=site.ycsb.workloads.CoreWorkload
readallfields=true
readproportion=0.2
updateproportion=0.3
scanproportion=0.3
insertproportion=0
readmodifywriteproportion=0.2
requestdistribution=zipfian
recordcount=1000
operationcount=1000
workload=site.ycsb.workloads.CoreWorkload
readallfields=true
readproportion=0.2
updateproportion=0.3
scanproportion=0.3
insertproportion=0
readmodifywriteproportion=0.2
requestdistribution=zipfian

```

## YCSB Run
1. To run YCSB, you need following the `load` command first:
```console
~/ycsb-0.17.0/bin/ycsb.sh load mongodb -s -P ~/ycsb-0.17.0/workloads/iworkload -p recordcount=10000000 -threads 256 -p mongodb.url="mongodb://${mongo_ip}:${mongo_port}/mymongodb"
```
You can see the result after the `load` command finishes:
```out
## Run YCSB
To run YCSB, you need following the `load` command first:
```console
~/ycsb-0.17.0/bin/ycsb.sh load mongodb -s -P ~/ycsb-0.17.0/workloads/iworkload -p recordcount=10000000 -threads 256 -p mongodb.url="mongodb://${mongo_ip}:${mongo_port}/mymongodb"
```

Replace `mongo_ip` and `mongo_port` in the command above with the IP address and port number of the machine you are running MongoDB on.

You should see the result from the benchmark after the `load` command finishes:
```output
/usr/bin/java -classpath /root/workload/tools/ycsb-0.17.0/conf:/root/workload/tools/ycsb-0.17.0/lib/core-0.17.0.jar:/root/workload/tools/ycsb-0.17.0/lib/HdrHistogram-2.1.4.jar:/root/workload/tools/ycsb-0.17.0/lib/htrace-core4-4.1.0-incubating.jar:/root/workload/tools/ycsb-0.17.0/lib/jackson-core-asl-1.9.4.jar:/root/workload/tools/ycsb-0.17.0/lib/jackson-mapper-asl-1.9.4.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/logback-classic-1.1.2.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/logback-core-1.1.2.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/mongodb-async-driver-2.0.1.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/mongodb-binding-0.17.0.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/mongo-java-driver-3.8.0.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/slf4j-api-1.7.25.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/snappy-java-1.1.7.1.jar site.ycsb.Client -load -db site.ycsb.db.MongoDbClient -s -P /root/workload/tools/ycsb-0.17.0/workloads/iworkloadf -p recordcount=10000000 -threads 256 -p mongodb.url=mongodb://172.26.202.189:27017/mymongodb
mongo client connection created with mongodb://172.26.202.189:27017/mymongodb
[OVERALL], RunTime(ms), 241978
Expand All @@ -80,16 +87,20 @@ requestdistribution=zipfian
[INSERT], 95thPercentileLatency(us), 7563
[INSERT], 99thPercentileLatency(us), 14991
[INSERT], Return=OK, 10000000
```
```

You can now benchmark the performance of MongoDB following the `run` command:
```console
~/ycsb-0.17.0/bin/ycsb.sh run mongodb -s -P ~/ycsb-0.17.0/workloads/iworkload -p operationcount=5000000 -threads 256 -p mongodb.url="mongodb://${mongo_ip}:${mongo_port}/mymongodb"
```
Replace `mongo_ip` and `mongo_port` in the command above with the IP address and port number of the machine you are running MongoDB on.

2. Then you can benchmark the performance of MongoDB following the `run` command:
```
~/ycsb-0.17.0/bin/ycsb.sh run mongodb -s -P ~/ycsb-0.17.0/workloads/iworkload -p operationcount=5000000 -threads 256 -p mongodb.url="mongodb://${mongo_ip}:${mongo_port}/mymongodb"
```
__Attention: Please ensure that you have sufficient disk space available!__
{{% notice Note %}}
Please ensure that you have sufficient disk space available!
{{% /notice %}}

You can see the performance data after the `run` command execution is finished.
```output
You can see the performance data after the `run` command execution is finished.
```output
/usr/bin/java -classpath /root/workload/tools/ycsb-0.17.0/conf:/root/workload/tools/ycsb-0.17.0/lib/core-0.17.0.jar:/root/workload/tools/ycsb-0.17.0/lib/HdrHistogram-2.1.4.jar:/root/workload/tools/ycsb-0.17.0/lib/htrace-core4-4.1.0-incubating.jar:/root/workload/tools/ycsb-0.17.0/lib/jackson-core-asl-1.9.4.jar:/root/workload/tools/ycsb-0.17.0/lib/jackson-mapper-asl-1.9.4.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/logback-classic-1.1.2.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/logback-core-1.1.2.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/mongodb-async-driver-2.0.1.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/mongodb-binding-0.17.0.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/mongo-java-driver-3.8.0.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/slf4j-api-1.7.25.jar:/root/workload/tools/ycsb-0.17.0/mongodb-binding/lib/snappy-java-1.1.7.1.jar site.ycsb.Client -t -db site.ycsb.db.MongoDbClient -s -P /root/workload/tools/ycsb-0.17.0/workloads/iworkloadf -p operationcount=5000000 -threads 256 -p mongodb.url=mongodb://172.26.202.189:27017/mymongodb
mongo client connection created with mongodb://172.26.202.189:27017/mymongodb
[OVERALL], RunTime(ms), 774685
Expand Down Expand Up @@ -136,6 +147,5 @@ requestdistribution=zipfian
[SCAN], 95thPercentileLatency(us), 101183
[SCAN], 99thPercentileLatency(us), 125375
[SCAN], Return=OK, 1499379

```
```

Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,15 @@ weight: 3 # 1 is first, 2 is second, etc.
layout: "learningpathall"
---

You are now ready to start MongoDB utilizing the newly built glibc with LSE on your Arm server.
In this section you will learn how to start using MongoDB with the newly built glibc with LSE on your Arm machine.


## MongoDB Setups
Build and install MongoDB version `5.3.2`:
## MongoDB Setup

Build and install MongoDB version `5.3.2` from source using the commands shown:

```console
#for Fedora/RHEL
sudo yum install -y git gcc g++ python3-devel openssl-devel libcurl-devel
#for Ubuntu/Debian
sudo apt install -y git gcc g++ python-dev-is-python3 python3-pip libssl-dev libcurl4-openssl-dev liblzma-dev

export PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring

cd ~
Expand All @@ -28,37 +26,54 @@ sudo python3 -m pip install -r etc/pip/compile-requirements.txt
sudo python3 buildscripts/scons.py install-mongod -j$(expr $(nproc) - 1) --disable-warnings-as-errors
```

## MongoDB Starts utilizing the newly built Glibc with LSE
## Configure and run MongoDB utilizing the newly built Glibc with LSE

Create a directory for MongoDB to store its data files:

```console
cd ~
mkdir -p ~/mongodb-5.3.2/data
vi ~/mongodb-5.3.2/mongodb.conf
```

Create a file named `mongodb.conf` in the ~/mongodb-5.3.2 directory using a file editor of your choice.
Copy and save the contents shown below into this configuration file:

```console
dbpath=mongodb-5.3.2/data
logpath=mongodb-5.3.2/mongodb.log
pidfilepath=mongodb-5.3.2/data/mongo.pid
logappend=true
bind_ip=0.0.0.0
port=27017
```
You can now run MongoDB as shown:

#if necessary
#rm -rf /mongodb-5.3.2/data/*
```console
cp /usr/lib/aarch64-linux-gnu/libcrypt.so ~/glibc-2.32_build_install/build/crypt/
~/glibc-2.32_build_install/build/testrun.sh ~/mongo/build/install/bin/mongod -f ~/mongodb-5.3.2/mongodb.conf --wiredTigerCacheSizeGB=20
```

#If you encounter an error related to libcrypt.so and need to execute the following command before running again:
#cp /usr/lib/aarch64-linux-gnu/libcrypt.so ~/glibc-2.32_build_install/build/crypt/
Confirm that the workload mongodb runs is with the newly built glibc with LSE:

First, get the pid with the following command.
```console
ps -ef | grep mongo
```

Confirm if the workload mongodb runs with the newly built glibc with LSE:
- First, get the pid with the following command.
```console
ps -ef | grep mongo
The output will look similar to:

```output
root 19852 1 1 16:33 ? 00:00:01 /root/glibc-2.32_build_install/build/elf/ld-linux-aarch64.so.1 --library-path /root/glibc-2.32_build_install/build:/root/glibc-2.32_build_install/build/math:/root/glibc-2.32_build_install/build/elf:/root/glibc-2.32_build_install/build/dlfcn:/root/glibc-2.32_build_install/build/nss:/root/glibc-2.32_build_install/build/nis:/root/glibc-2.32_build_install/build/rt:/root/glibc-2.32_build_install/build/resolv:/root/glibc-2.32_build_install/build/mathvec:/root/glibc-2.32_build_install/build/support:/root/glibc-2.32_build_install/build/crypt:/root/glibc-2.32_build_install/build/nptl /root/mongo/build/install/bin/mongod -f /mongodb-5.3.2/mongodb.conf --wiredTigerCacheSizeGB=20
```
```

- Then execute the following command to check.
```
cat /proc/19852/smaps | grep glibc
Next, execute the following command using the correct `pid`:

```console
cat /proc/19852/smaps | grep glibc
```
The output should look similar to:

```output
ffff898c5000-ffff898cd000 r-xp 00000000 103:02 953511 /root/glibc-2.32_build_install/build/crypt/libcrypt.so
ffff898cd000-ffff898e4000 ---p 00008000 103:02 953511 /root/glibc-2.32_build_install/build/crypt/libcrypt.so
ffff898e4000-ffff898e5000 r--p 0000f000 103:02 953511 /root/glibc-2.32_build_install/build/crypt/libcrypt.so
Expand Down Expand Up @@ -90,5 +105,6 @@ Confirm if the workload mongodb runs with the newly built glibc with LSE:
ffff90333000-ffff90355000 r-xp 00000000 103:02 943577 /root/glibc-2.32_build_install/build/elf/ld.so
ffff90372000-ffff90373000 r--p 0002f000 103:02 943577 /root/glibc-2.32_build_install/build/elf/ld.so
ffff90373000-ffff90375000 rw-p 00030000 103:02 943577 /root/glibc-2.32_build_install/build/elf/ld.so

```

This output shows that the newly built glibc with LSE is being utilized.