Tag: performance

  • Project “NVIDIA HPC Infiniband Homelab GPU Cluster”: Part 3: RDMA Performance Testing

    Project “NVIDIA HPC Infiniband Homelab GPU Cluster”: Part 3: RDMA Performance Testing

    Before moving on to Part 3 of this project, lets review what we have accomplished thus far.

    In Part 1 and Part 2 we have…

    • Did a bit of planning and scoping
    • Built a 3-node GPU cluster (viper, columbia, prometheus)
    • Interconnected with InfiniBand Installed and validated ConnectX-4 NICs and RDMA stack (mlx5, ib_core, etc.)
    • Brought up the InfiniBand fabric using OpenSM (links active, LIDs assigned)
    • Verified topology and connectivity (ibstat, ibnetdiscover)
    • Configured IP over InfiniBand for basic networking between nodes Identified PCIe/NUMA limitations affecting optimal GPU↔NIC performance

    We are now ready to do some performance testing of our Infiniband network.


    Pre-Test Setup

    Before we can get started on our perf testing we have bit of work to do. We are going to install a few packages, and configure some tunables.

    Diagnostic Tools

    First lets make sure that we have a couple tools installed, so lets install some rpms.

    sudo dnf install infiniband-diags libibverbs-utils librdmacm-utils -y

    Kernel Modules

    InfiniBand and GPUDirect require specific modules to load at boot. So lets create hpc.conf in /etc/modules-load.d/. This creates (or overwrites) /etc/modules-load.d/hpc.conf. This file ensures each module loads automatically at boot via systemd-modules-load. Run this on each host.

    sudo tee /etc/modules-load.d/hpc.conf >/dev/null <<'EOF'
    ib_ipoib
    ib_umad
    ib_uverbs
    nvidia-peermem
    EOF

    Then force load the modules.

    sudo modprobe ib_ipoib ib_umad ib_uverbs nvidia-peermem

    Below is a short breakdown/description for each module.

    ModuleHow it’s used
    ib_ipoibProvides IP networking over InfiniBand (e.g., ib0) for SSH, NFS, TCP/IP
    ib_umadEnables userspace IB management tools (e.g., ibstat, fabric queries)
    ib_uverbsCore RDMA interface used by applications (MPI, NCCL, libibverbs)
    nvidia-peermemEnables GPUDirect RDMA for direct GPU ↔ NIC memory transfers (no CPU copy)

    Locked Memory Limits

    RDMA works by “pinning” memory so the OS cannot swap it to disk. So we need to create /etc/security/limits.d/99-hpc.conf as shown below.

    sudo tee /etc/security/limits.d/99-hpc.conf >/dev/null <<'EOF'
    * soft memlock unlimited
    * hard memlock unlimited
    EOF

    Performance & RDMA Benchmarking

    Health Check

    First lets run the following commands on any host under test, just to make sure the InfiniBand network is healthy before we start any testing. Run each line individually and make note of the output.

    hostname
    ibstat
    ibv_devinfo | egrep 'hca_id|transport|fw_ver|port:|link_layer|active_mtu|sm_lid|port_lid'

    You are specifically interesting in the following

    • Device Present (mlx5)
    • State: Active
    • Physical state: LinkUp
    • Link layer: InfiniBand

    Confirm HCA Name and Port Number

    Run on any device under test – we will need this for our test on our receiver and sender side.

    ibv_devices

    Output from columbia.lab.

     device          	   node GUID
     ------          	----------------
     mlx5_0          	248a070300ac5414
    
    

    Output from prometheus.lab

     device          	   node GUID
     ------          	----------------
     mlx5_0          	248a070300ac5610
    
    

    Run the RDMA Latency Test

    For our ib_send_lat (latency test) our device IP addresses are as follows.

    • columbia.lab – 172.16.50.12
    • prometheus.lab -172.16.50.11

    On our first device, columbia.lab, we run the following and leave it running.

    ib_send_lat -d mlx5_0 -i 1

    Now over on prometheus, run the command below. Insert the IP from columbia captured above. You will see a good bit of output in your terminal window.

    ib_send_lat -d mlx5_0 -i 1 <columbia_ip>

    Key configuration details

    So assuming the test did not fail, you are going to see some data spit out. Lets make sense of some of it.

    ParameterValueMeaning
    Devicemlx5_0ConnectX-4 (mlx5 driver)
    TransportIB (RC)Reliable Connection (standard RDMA mode)
    MTU4096Optimal for IB performance
    Queue Pairs1Single stream test
    Inline data236BSmall messages optimized
    Link typeInfiniBandCorrect mode

    What this test is actually doing

    ib_send_lat:

    • Registers memory with the NIC
    • Creates RDMA queue pairs
    • Sends messages using:
      • ibv_post_send()
    • Measures completion latency via completion queues (CQs)

    This is direct RDMA messaging, not IP networking.

    Our Overall results

    • Average latency: ~1.15 µs
    • Typical latency: ~1.14 µs
    • Minimum latency: 1.06 µs
    • Outliers: up to 11.41 µs
    • Conclusion: Healthy RDMA performance

    While InfiniBand ≠ RDMA test by default, our test ib_send_lat specifically uses RDMA verbs, so a successful result proves RDMA is working.

    In the output above, our average latency confirms that RDMA is functioning, as is kernel bypass. Note, that while we are using TCP/IP to setup the test, the actual data transfer is NIC to NIC and memory to memory. The queue pair exchange confirms RDMA session, as QPs were created on both nodes and transitioned through the required queue pair states shown below.

    StateNamePurposeAnalogy
    INITInitializeLocal QP setupPhone powered on
    RTRReady to ReceiveCan receive remote dataYou know the other person’s number
    RTSReady to SendFully operational (send + receive)Call connected and talking

    Run the RDMA Bandwidth Test

    For this test we will run ib_send_bw. This test measures the following.

    • Throughput (bandwidth) of RDMA send operations
    • NIC-to-NIC data transfer rate
    • Memory → NIC → fabric → NIC → memory

    Again this test uses IP to establish the initial connection between nodes, but make no mistake we are using RDMA verbs and are testing IB traffic (not IP traffic).

    So over on our first node (columbia.lab) we run the following.

    ib_send_bw -d mlx5_0 -i 1 -a

    Why these flags

    FlagPurpose
    -d mlx5_0Select your ConnectX-4 device
    -i 1Use IB port 1
    -aSweep all message sizes

    And on our second node we run the command shown below.

    ib_send_bw -d mlx5_0 -i 1 -a <columbia_ip>

    Assuming that this command does not fail, you will see a bunch of output that we need to interpret. This output is truncated, but I wanted to give you an idea of what to expect in the output.

    ib_send_bw -d mlx5_0 -i 1 -a 172.16.50.12
    ---------------------------------------------------------------------------------------
    Send BW Test
    Dual-port : OFF Device : mlx5_0
    Number of qps : 1 Transport type : IB
    Connection type : RC Using SRQ : OFF
    PCIe relax order: ON Lock-free : OFF
    WARNING: CPU is not PCIe relaxed ordering compliant.
    WARNING: You should disable PCIe RO with `--disable_pcie_relaxed` for both server and client.
    ibv_wr* API : ON Using DDP : OFF
    TX depth : 128
    CQ Moderation : 100
    CQE Poll Batch : 16
    Mtu : 4096[B]
    Link type : IB
    Max inline data : 0[B]
    rdma_cm QPs : OFF
    Data ex. method : Ethernet
    ---------------------------------------------------------------------------------------
    local address: LID 0x02 QPN 0x0107 PSN 0xed831e
    remote address: LID 0x01 QPN 0x0107 PSN 0xa2c511
    ---------------------------------------------------------------------------------------
    #bytes #iterations BW peak[MiB/sec] BW average[MiB/sec] MsgRate[Mpps]
    Conflicting CPU frequency values detected: 1200.000000 != 1300.046000. CPU Frequency is not max.
    2 1000 7.79 7.40 3.879797

    Keep in mind that our IB bottleneck is our 40Gbe IB Switch. Here is what we can interpret from our test data.

    • Plateau was about: 3776.9 MiB/s which is about 31.7 Gbit/s
    • That is a normal practical result for a nominal 40 Gb InfiniBand-class link
    • Our plateau is consistent and stable, which is good

    Our InfiniBand link is healthy enough to sustain near-expected throughput, there are no obvious severe bottleneck or broken configuration. We are seeing some GPU frequency warnings, and some “PCIe relaxed ordering” warnings so lets fix those any try the test again.

    What is PCIe Relaxed Ordering? PCIe Relaxed Ordering is a performance feature where The CPU/NIC is allowed to reorder memory transactions. This can improve throughput by reducing stalls and increasing parallelism

    On both hosts, run the command below.

    cpupower frequency-set -g performance


    Now back on the first host, kick off the listen side of the test.

    ib_send_bw -d mlx5_0 -i 1 -a -q 4 --disable_pcie_relaxed

    And on the other server we kick off the test itself.

    ib_send_bw -d mlx5_0 -i 1 -a -q 4 --disable_pcie_relaxed <columbia_ip>

    Why these flags

    FlagPurpose
    -d mlx5_0Select your ConnectX-4 device
    -i 1Use IB port 1
    -aSweep all message sizes
    -q 4Use multiple queue pairs (better utilization)
    --disable_pcie_relaxedMatch your CPU capabilities and remove warning

    So lets summarize our output.

    • Almost identical throughput as initial test
    • Slight improvement in consistency
    • Cleaner test conditions (set cpu-frequency to performance)
    • Multiple QPs established (we see 4 QPNs)
    • We still see CPU Frequency is not max, however this is non issue as we have already saturated our links.


    Wrap Up

    In our previous post, we stood up our IB network, and performed some basic fabric tests. Today was all about performance testing and testing with the actual RDMA verb stack. We found that our fabric was pretty much performing as expected out of the box with minimal tuning, as we are hitting near-theoretical limits for our 40Gb hardware.

    We have a stable, low latency, high bandwidth IB Fabric.

    I was hoping to get to GPU direct testing today, however that looks like it might a bit of a beast and I think I will call it a day and do a bit more research on the topic.

  • CEPH: TCP Performance Tuning

    ethernet-cable-fade

    Below are a few TCP tunables that I ran into when looking into TCP performance tuning for CEPH.

    Note that there are two separate sections for 10GE connectivity, so you will want to test with both to find what works best for your environment.

    To implement, we just add what is below to /etc/sysctl.d/99-sysctl.conf and run “sysctl -p“. Changes are persistent across reboots. Ideally these TCP tunables should be deployed to all CEPH nodes (OSD most importantly).

    [code language=”css”]
    ## Increase Linux autotuning TCP buffer limits
    ## Set max to 16MB (16777216) for 1GE
    ## 32MB (33554432) or 54MB (56623104) for 10GE

    # 1GE/16MB (16777216)
    #net.core.rmem_max = 16777216
    #net.core.wmem_max = 16777216
    #net.core.rmem_default = 16777216
    #net.core.wmem_default = 16777216
    #net.core.optmem_max = 40960
    #net.ipv4.tcp_rmem = 4096 87380 16777216
    #net.ipv4.tcp_wmem = 4096 65536 16777216

    # 10GE/32MB (33554432)
    #net.core.rmem_max = 33554432
    #net.core.wmem_max = 33554432
    #net.core.rmem_default = 33554432
    #net.core.wmem_default = 33554432
    #net.core.optmem_max = 40960
    #net.ipv4.tcp_rmem = 4096 87380 33554432
    #net.ipv4.tcp_wmem = 4096 65536 33554432

    # 10GB/54MB (56623104)
    net.core.rmem_max = 56623104
    net.core.wmem_max = 56623104
    net.core.rmem_default = 56623104
    net.core.wmem_default = 56623104
    net.core.optmem_max = 40960
    net.ipv4.tcp_rmem = 4096 87380 56623104
    net.ipv4.tcp_wmem = 4096 65536 56623104

    ## Increase number of incoming connections. The value can be raised to bursts of request, default is 128
    net.core.somaxconn = 1024

    ## Increase number of incoming connections backlog, default is 1000
    net.core.netdev_max_backlog = 50000

    ## Maximum number of remembered connection requests, default is 128
    net.ipv4.tcp_max_syn_backlog = 30000

    ## Increase the tcp-time-wait buckets pool size to prevent simple DOS attacks, default is 8192
    net.ipv4.tcp_max_tw_buckets = 2000000

    # Recycle and Reuse TIME_WAIT sockets faster, default is 0 for both
    net.ipv4.tcp_tw_recycle = 1
    net.ipv4.tcp_tw_reuse = 1

    ## Decrease TIME_WAIT seconds, default is 30 seconds
    net.ipv4.tcp_fin_timeout = 10

    ## Tells the system whether it should start at the default window size only for TCP connections
    ## that have been idle for too long, default is 1
    net.ipv4.tcp_slow_start_after_idle = 0

    #If your servers talk UDP, also up these limits, default is 4096
    net.ipv4.udp_rmem_min = 8192
    net.ipv4.udp_wmem_min = 8192

    ## Disable source redirects
    ## Default is 1
    net.ipv4.conf.all.send_redirects = 0
    net.ipv4.conf.all.accept_redirects = 0

    ## Disable source routing, default is 0
    net.ipv4.conf.all.accept_source_route = 0
    [/code]

    Reference here

  • HomeLab Adventures: Freenas Volume 1

    Humpty_Dumpty

     

     So I am not going to lie, I am a very sick man, but I am also not afraid to admit it. I have a terrible, terrible addiction which is my homelab.

     

    It all started out so innocently… An old Sun Ultra 5 to learn Sparc Solaris at home.. A couple of desktops converted over to rack mount cases and racked in a cheap telecom rack in my unfinished basement.

     

    This was very early in my career when I had a lot to learn and plenty of free time to study. However that was many moons ago.

     

    I measure the time that has past since then by the amount of gray that has crept into my beard. As I moved from one role to the next, I found that I had the pick of the litter when it came to retired equipment.

     

    Previously I would have been lucky to land an old Xeon (without virtualization support) to take home, something chock full of PCI-X cards (or worse, SCSI) that were useless to me in a desktop. However now I was landing quad core Nehalems (perfect for virtualization) with handfuls of memory and sexy pci-e SAS/Sata raid controllers.

     

    Oh and tons of SSDs that were considered too small not 6 months after they were unboxed. Let’s not even get into my networking setup… as that is a tale for a different day.

     

    Once I had a deployed a couple of very nice and fully loaded ESX servers, I came to find that the performance bottleneck in my lab was storage. Sure I had terabytes of SAS and SATA disk, but it was all local. I had nothing that allowed me to fail over between host. Thus began a quest.. a quest for the ages.

     

    Knowing myself as I do, I knew that I was not going to be satisfied by throwing a cheap NAS together out of a couple or SATA disk. No, desktop performance was not going to cut it. I needed 15k SAS, a raid controller with battery backup, a handful of spindles, and a beefy tower to allow for plenty of expansion (yes, all my machines were converted to towers). I also knew I was going to need to use LACP or some other network bonding to cable my creation into my network. Heck, I even dared check out the cost of a cheap 10Gb small business class switch (yup too expensive… lets wait a year or so).

    Which brings us to today. The day I fired up my first freenas box.

    My rough specs are as follows.

    • Gigabyte Z97-HD3
    • Intel Core i3 3.8Ghz
    • 5x600gb 15K SAS -Raid-Z1
    • 1x32gGB SSD
    • 2x4tb 7k SATA – Raid 1
    • 16GB Memory
    • LSI 9260 8i

    So now what – move some VMS onto it and call it a day. Well that’s no fun. Lets see what kind of performance we can push through this baby. I mean after all, we are not using 15k SAS drives for nothing.

    Side note, it’s not exactly plug and play when it comes to using SAS drives in a standard tower. Even if you have a SAS capable controller, you are going to need a backplane of some sort to provide power and i/o connectivity. Finding something that will fit the bill, without having to use a cheap one-off backplane is a challenge to say the least. For my lab I picked up a couple of these. 99% of what you see in the box stores will not support SAS drives, and its not always obvious at first glance… you have to check the specs on the side of the box. Also don’t walk into Fry’s thinking you will find one… I have tried. Microcenter seems to be the only large chain that stocks an internal SAS enclosure.

    For testing I am have ssh’d into a linux desktop that is on the same network as the freenas box. The desktop has only 1gb network interface. Both systems a cabled northbound to a Cisco 3560g.

    First let’s mount up our RaidZ-1 volume by sticking this in our /etc/fstab and running mount  /mnt.

    freenas:/mnt/freenas-vol-1      /mnt    nfs rsize=8192,wsize=8192,timeo=14,intr

    Boom, there it is our new fancy mount. Now to run the tests. However that will come in part 2 as I plan not to rush through this. As far as I understand, there can be a bit of tuning in Freenas, so it might take me a bit to get everything dialed in.

    Turn an Old Computer Into a Do-Anything Home Server with FreeNAS 8
    Configuring ZFS on FreeNAS for backup storage from a Windows Domain
    Sync Hacks: How to Set Up FreeNAS with BitTorrent Sync Using a Plugin
    RHEL6 – Quick and Dirty NFS How To

     

  • Basic AIX Performance Troubleshooting Commands

    600px-Orange_x.svgWow, today I logged into my first AIX Server in about 4.5 years. It was a horrible experience. I’ve been working with Redhat/CentOS pretty much exculsively for so long, I was mostly helpless to do anything of importance on the CLI other than create a few users and move some files around.  None of the common commands that I am so used to using even exist in AIX.

    Figured I would do a bit of homework and figure out how to do some basic troubleshooting before I was in a server down situation with no idea how to troubleshoot.

    Checking Free Memory

    To check free memory on a box use the svmon command.

    svmon -G

    Overall System Status

    For this you will probably want to use topas, which is pretty simiar to top. Topas gives you a quick and dirty overview of what is going on on a system. Here you can find CPU usage, top processes, disk utililization. Check out the fancy screen shot below.

    Top-ass1

    List Volume Groups

    Wow, Linux has really confused me on this one. Anyway, use lsvg

    # lsvg -o
    rootvg
    crsrdb_bin
    crsprdb_data
    crsprdb_index
    crsprdb_arch
    crsprdb_rman

    List Info About a Volume Group.

    lsvg rootvg

    Display Names of all Logical Volumes in a Volume Group.

    # lsvg -l rootvg

    Display Physical Memory

    # lsattr -El sys0 -a realmem

    Finding Disk I/O Issues

    Sar appears to be a fine option here. Especially since I am looking for percent busy. Iostat also exists on AIX, btw.

    # sar -d 1 2

    Show Network Throughput

    The more I poke around the internet trying to figure out how to actually use AIX the more I keep running into topas. Anyway this one is a good one

    #topas -E

    I plan to have more of these one liners documented here in the future, but for now this is going to have to do.