Linux Threads and Hyper-Threading

1. Definition

A thread is an execution flow of a process and is the basic unit of CPU scheduling and dispatching. It is a smaller unit that can run independently compared to a process.

A process consists of several threads, and threads belonging to the same process share all the resources owned by the process. For a single-core CPU, tasks are executed alternately; task 1 runs for 0.01 seconds, switches to task 2, task 2 runs for 0.01 seconds, then switches to task 3, and so on. Although it appears that each task is executed alternately, due to the CPU’s extremely fast execution speed, we feel as if all tasks are executing simultaneously.

Hyper-threading is a technology proposed by Intel that simulates multiple logical threads on a single physical CPU core (AMD’s similar technology is called SMT, Simultaneous Multithreading). Its core goal is to improve CPU parallel efficiency by allowing a single physical core to handle multiple threads simultaneously by sharing the execution resources within the CPU core.

Using hyper-threading technology, the two simulated logical cores share the same CPU resources, allowing two threads to occupy CPU resources at the same time. Therefore, both threads can be executed, achieving parallel operation of two threads at the same time.

Traditional Single-Threaded Core vs. Hyper-Threaded Core

Feature Traditional Single-Threaded Core Hyper-Threaded Core
Execution Capability Each physical core can only execute 1 thread at the same time Each physical core can execute 2 threads simultaneously
Resource Utilization Efficiency CPU resources are idle when a thread is blocked When one thread is blocked, the other thread can continue to use the idle resources
Applicable Scenarios Compute-intensive tasks (e.g., scientific computing, 3D rendering) I/O-intensive tasks (e.g., web servers, database queries)
Hardware Resource Allocation Exclusive access to all core resources Shares core computing units (ALU/FPU), independent register sets
Performance Improvement Potential No additional concurrency advantage Lightweight tasks can improve throughput by 10% to 30%

If the number of threads specified in a multi-threaded program far exceeds the system’s logical thread count, for example, specifying 128 or 256 threads on a CPU with 64 logical threads, it can lead to severe performance degradation and resource contention, potentially making it slower than single-threaded execution. The relationship between the two is parabolic. Therefore, it is necessary to flexibly adjust the number of threads based on your machine; more is not always better.

2. Viewing System Thread Information

# Understand the number of CPUs, cores, and threads in the system

cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l
cat /proc/cpuinfo | grep "core id" | sort | uniq | wc -l
cat /proc/cpuinfo | grep "processor" | sort | uniq | wc -l

# Output

(base) $ cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l
2
(base) $ cat /proc/cpuinfo | grep "core id" | sort | uniq | wc -l
16
(base) $ cat /proc/cpuinfo | grep "processor" | sort | uniq | wc -l
64

# 2 physical CPUs, each with 16 physical cores, totaling 32 physical cores, 32 physical cores × 2 hyper-threads = 64 logical threads
# Check if hyper-threading is enabled on the current system

lscpu | grep "Thread(s) per core"

# Output

Thread(s) per core: 1 → Hyper-threading not enabled (each physical core has only 1 logical thread)
Thread(s) per core: 2 → Hyper-threading enabled (each physical core has 2 logical threads)

3. Parallel Tool GNU Parallel

GNU Parallel is a shell tool designed to execute computational tasks in parallel on one or more computers. A computational task can be a shell command or a script program that takes each line as input. Typical inputs include lists of files, hosts, users, URLs, or tables; a computational task can also be a command read from a pipe. GNU Parallel chunks the input and executes it in parallel through pipes.

#!/bin/bash

# Define reference genome path
ref_genome="ref_genome.fasta"

# Define output folder paths
folder_01="folder_01"
folder_02="folder_02"

# Create output folders
mkdir -p "$folder_01"
mkdir -p "$folder_02"

# Define sample file list
samples_file="samples.txt"

# Define function to process each sample
process_sample() {
  sample_path=$1
  ref_genome=$2
  folder_01=$3
  folder_02=$4

  # Get sample file name (without path)
  sample_name=$(basename "$sample_path")

  # Example of blastn alignment
  echo "Processing sample: $sample_name"
  blastn -query "$sample_path" -subject "$ref_genome" -out "$folder_01/${sample_name}.blast" -outfmt 6
  awk '{print $1, $2, $3, $4}' "$folder_01/${sample_name}.blast" > "$folder_02/${sample_name}.result"
}

export -f process_sample  # Export function for parallel use

# Use parallel to process multiple samples in parallel
parallel -j 3 process_sample {} ${ref_genome} ${folder_01} ${folder_02} :::: ${samples_file}

# Wait for all parallel tasks to complete
wait

echo "All samples processed!"
  • • The process_sample function takes four parameters: sample path, reference genome path, folder 01, and folder 02, passed by position.
  • • Uses the parallel tool to run the process_sample function in parallel.
  • • The -j 3 parameter indicates that 3 tasks will run simultaneously (can be adjusted based on your CPU core and thread count).
  • • :::: ${samples_file} indicates reading sample file paths from samples.txt, one sample per line. :::: is used to specify the input source file and must be placed at the end of the command.

4. Reference Links

https://blog.csdn.net/wangguchao/article/details/109002488

https://blog.csdn.net/weixin_40192882/article/details/136072504

Linux Threads and Hyper-Threading

From “But You Are Really Really Cute”

Leave a Comment