Linux 내에서 하이퍼 스레딩 비활성화 (BIOS에 액세스 할 수 없음)


26

원격 시설에서 금융 거래 응용 프로그램을 실행하는 시스템이 있습니다. ILO / DRAC에 액세스 할 수 없지만 하이퍼 스레딩을 비활성화해야합니다. 이 시스템은 Intel Westmere 3.33GHz X5680 16 진 코어 CPU를 실행합니다. 재부팅 할 수 있지만 성능 문제로 인해 시스템이 하이퍼 스레딩을 활성화하지 않도록하려고합니다. Linux 내에서이를 수행하는 명확한 방법이 있습니까?

편집 : noht커널 부팅 명령 줄에 추가 된 지시문이 작동하지 않았습니다. RHEL도 마찬가지입니다.

참조 : https://bugzilla.redhat.com/show_bug.cgi?id=440321#c9

답변:


21

원하는 경우 런타임에이를 수행 할 수 있습니다. 나는 여기에 설명 된 좋은 해결책을 찾았습니다 : http://www.absolutelytech.com/2011/08/01/how-to-disable-cpu-cores-in-linux/

1 단계 : 끄려는 Linux CPU를 식별하십시오.

cat /proc/cpuinfo

동일한 "코어 ID"를 가진 CPU를 찾으십시오. 각 쌍 중 하나를 끄십시오.

2 단계 : 하이퍼 스레딩 CPU 끄기 (필자의 경우 Linux에서 볼 수있는 총 8 개의 "CPU"중 마지막 4 개)

echo 0 > /sys/devices/system/cpu/cpu4/online
echo 0 > /sys/devices/system/cpu/cpu5/online
echo 0 > /sys/devices/system/cpu/cpu6/online
echo 0 > /sys/devices/system/cpu/cpu7/online

시스템 시작 직후에 실행하는 스크립트를 스스로 설정할 수 있습니다.


1
그것은 작동 거의 내가 예상대로. 가상 코어가 비활성화되었습니다. 이제 CPU 소비 스레드 하나를 실행하면 실제 코어가 100 %로드됩니다. 그러나 sysbench --num-threads=1 --test=cpu run다른 num-thread와 함께 사용 하고 HT를 켜거나 끄면 HT를 비활성화하면 스레드가 많을 때 성능이 저하되고 스레드가 하나만 있어도 HT를 끄면 아무런 이점이 없습니다. 따라서 그대로 두는 것이 좋습니다. 최적입니다.
Sergey P. 일명 azure

다시 켜는 명령이 무엇인지 알고 있습니까? 답변 시작 부분의 링크가 죽었습니다 ~. 감사!
user189035

@ user189035 : echo 1대신 echo 0다시 켜야합니다.
Peter Cordes

@ SergeyP.akaazure, 금융 서비스 응용 프로그램의 경우 HT를 끄는 주된 이유는 성능이 아니라 보안입니다.
Simon Richter

@SimonRichter이 질문이 처음 작성된 시점은 실제로 성능이었습니다. SMT / HT는 그 당시 CPU의 일부 워크로드에서 거의 좋지 않았습니다. Meltdown / Spectre와 가장 최근의 Foreshadow 공격은 몇 년 후 일어났습니다.
Michael Hampton

14

컴퓨터 시작시 하이퍼 스레딩을 비활성화하는 스크립트 ...

하이퍼 스레딩을 비활성화하려면 /etc/rc.local 컴퓨터에 스크립트를 포함시킵니다. 완전히 깨끗하지는 않지만 CPU 아키텍처와 무관하게 설치가 쉽고 최신 Linux 배포판에서 작동해야합니다.

nano /etc/rc.local

    # place this near the end before the "exit 0"

    for CPU in /sys/devices/system/cpu/cpu[0-9]*; do
        CPUID=$(basename $CPU)
        echo "CPU: $CPUID";
        if test -e $CPU/online; then
                echo "1" > $CPU/online; 
        fi;
        COREID="$(cat $CPU/topology/core_id)";
        eval "COREENABLE=\"\${core${COREID}enable}\"";
        if ${COREENABLE:-true}; then        
                echo "${CPU} core=${CORE} -> enable"
                eval "core${COREID}enable='false'";
        else
                echo "$CPU core=${CORE} -> disable"; 
                echo "0" > "$CPU/online"; 
        fi; 
    done;    

어떻게 작동합니까?

Linux 커널 정보 및 컨트롤은 최신 Linux 배포판의 / sys 디렉토리에 파일로 액세스 할 수 있습니다. 예를 들면 다음과 같습니다.

/ sys / devices / system / cpu / cpu3 에는 커널 정보와 논리 CPU 3에 대한 컨트롤이 포함되어 있습니다.

cat / sys / devices / system / cpu / cpu3 / topology / core_id 는이 논리적 CPU가 속한 코어 번호를 표시합니다.

echo "0"> / sys / devices / system / cpu / cpu3 / online 은 논리적 CPU 3을 비활성화 할 수 있습니다.

왜 작동합니까?

정확히 이유를 모르겠지만 ... 하이퍼 스레딩 기능이 꺼져 있으면 시스템의 응답 속도가 향상됩니다 (i5 노트북 및 60 개 이상의 코어가있는 대규모 Xeon 서버에서). CPU 당 캐시, CPU 당 메모리 할당, CPU 스케줄러 할당 및 프로세스 우선 순위 복잡한 반복과 관련이 있다고 생각합니다. 하이퍼 스레딩의 이점은 사용 방법을 알고있는 CPU 스케줄러를 만드는 복잡성으로 인해 과체중이라고 생각합니다.

필자의 경우, 하이퍼 스레딩의 문제점은 논리 코어 수만큼 CPU 집약적 스레드를 시작하면 CPU 집약적 작업에 대한 빠른 컨텍스트 전환이 있지만 하이퍼 스레딩이 완전히 소비 한 이후 백그라운드 작업에 대한 비싼 컨텍스트 전환이 발생한다는 것입니다. CPU 집약적 작업. 반면, 물리적 코어 수만큼 CPU 집약적 스레드를 시작하면 해당 작업에 대한 컨텍스트 전환과 백그라운드 작업에 대한 빠른 컨텍스트 전환이 없습니다. 좋은 것처럼 보이지만 백그라운드 작업은 무료 논리 프로세서를 발견하고 거의 즉시 실행됩니다. 마치 실시간 성능과 같습니다 (좋은 -20).

첫 번째 시나리오에서 하이퍼 스레딩은 uselles이며, 정상적인 처리로 하이퍼 스레딩을 최대한 사용했기 때문에 백그라운드 작업은 값 비싼 컨텍스트 스위치를 사용합니다. 내 CPU 성능의 최대 50 %가 백그라운드 작업에 우선 순위를두기 때문에 두 번째는 허용되지 않습니다.

내가 말하는 "CPU 집약적 인"작업은 인공 지능 데이터 마이닝 및 권한 부여 서버 (내 작업)입니다. 저렴한 컴퓨터와 클러스터에서 블렌더 렌더링 (내 미래의 집을 스케치하기 위해).

또한 이것은 추측입니다.

나는 더 나은 인상을 가지고 있지만 그렇지 않을 수도 있습니다.


내 스크립틀릿을 따라 가기가 더 쉽다고 생각합니다.
Paul M

9

실제로 오래된 커널 (Linux 2.6.9 정도)의 경우 부팅시 커널에 noht 매개 변수를 추가하십시오 .

이 커널 명령 행 옵션 은 Linux 2.6.18 이상부터 제거되었습니다 .


에서 http://www.faqs.org/docs/Linux-HOWTO/BootPrompt-HOWTO.html :

The `noht' Argument

This will disable hyper-threading on intel processors that have this feature. 

lilo를 사용하는 경우 /etc/lilo.conf를 편집하고 (나중에 lilo를 실행) grub을 사용하는 경우 /boot/grub/menu.lst를 편집하십시오.


이것은 기능적으로 BIOS에서 HT를 비활성화하는 것과 동일합니까?
ewwhite

나는 그것을 확실하게 알지 못하지만, 그래도 BIOS에서 그것을 비활성화하는 것과 동등한 것으로 기대하지는 않을 것입니다.
rems

2
젠투 시스템입니다. nohtgrub 커널 명령 행에서 항목을 시도했습니다 . 시스템이 noht명령을 존중하지 않았습니다 . RHEL도 마찬가지입니다. 참조 : bugzilla.redhat.com/show_bug.cgi?id=440321#c9
ewwhite

1
이것은 적어도 Linux 2.6.18 이후에는 사용되지 않습니다 . noht커널 옵션이 제거되었습니다. Linux는 HT가 켜져있는 경우에만 일부 Haswell 카운터 카운터 정오표 (BJ122, BV98, HSD29)에 대한 해결 방법을 사용할 수 있으며 initramfs 가로드 되기 전에 발생하기 때문에 불행 합니다.
Peter Cordes

9

각 코어에 대해 "thread_siblings_list"를 사용하여 HT 쌍에서 두 번째 코어를 끌 수 있습니다.

다음 명령 파이프 라인은 최적화되지 않았으며 이해하기 쉽도록이 방법으로 수행되었습니다.

cat /sys/devices/system/cpu/cpu*/topology/thread_siblings_list | \
awk -F, '{print $2}' | \
sort -n | \
uniq | \
( while read X ; do echo $X ; echo 0 > /sys/devices/system/cpu/cpu$X/online ; done )

따라서 모든 스레드 형제 목록을 가져 와서 각 쌍의 두 번째 CPU를 추출하고 고유 한 목록을 얻은 다음 끄십시오.

이게 말이 되요?

위의 실행 후 "cat / proc / cpuinfo"를 수행하면 코어 수가 반으로 줄어 듭니다.


이것은 좋은 대답입니다. 나는 내 목적을 위해 일을 다음과 같이 수정했다 : echo 0 > /sys/devices/system/cpu/cpu$X/online이된다echo 0 | sudo tee /sys/devices/system/cpu/cpu$X/online
탄소 양이온

5

최신 커널은 SMT (Simultaneous Multithreading) 제어를 제공합니다.

SMT의 상태는 다음을 통해 확인할 수 있습니다.

cat /sys/devices/system/cpu/smt/active

로 상태 변경

echo off > /sys/devices/system/cpu/smt/control

옵션은 다음과 같습니다.

  • 떨어져서
  • 강제

우리는 이것을 Linux Kernel 4.4.0에서 테스트했습니다


닉 안녕하세요 사이트에 오신 것을 환영합니다. 테스트 및 버전에 대한 정보는 매우 중요합니다.
kubanczyk

우수, 우분투 16.04.6 LTS에서 테스트
Geek

4

Lukas의 답변은 훌륭하지만 코어 ID가 HT 형제를 식별하는 데 도움이되지 않기 때문에 HT를 비활성화하는 데 실제로 작동하지 않습니다. 이 스크립트는 대신 작동합니다.

#!/bin/bash
for CPU in /sys/devices/system/cpu/cpu[0-9]*; do
    CPUID=`basename $CPU | cut -b4-`
    echo -en "CPU: $CPUID\t"
    [ -e $CPU/online ] && echo "1" > $CPU/online
    THREAD1=`cat $CPU/topology/thread_siblings_list | cut -f1 -d,`
    if [ $CPUID = $THREAD1 ]; then
        echo "-> enable"
        [ -e $CPU/online ] && echo "1" > $CPU/online
    else
        echo "-> disable"
        echo "0" > $CPU/online
    fi
done

당신의 대본은 나의 변형입니다. CPU가 여러 개인 경우 어떻게되는지 확인해야합니다.
Paul M

@PaulM 정확히 2 개의 소켓 Haswell 시스템을 테스트하고 제 목적으로 사용했습니다.
Anton

0

ILO / Drac에 들어갈 때까지 기다려야했습니다. 커널 부팅 매개 변수는 현재 Linux 배포에서 작동하지 않습니다.


0

libsmbios-bin 패키지 (Debian, Ubuntu 등)에는 바이너리 isCmosTokenActive 및 activateCmosToken이 있습니다. 토큰 목록 과 함께 다음과 같이 시도 할 수 있습니다.

# isCmosTokenActive 0x00d1 # CPU_Hyperthreading_Enable
[...] Type 0x00d1  Location 0x46 AND(fe) OR(0)  BITFIELD: 1
# isCmosTokenActive 0x00d2 # CPU_Hyperthreading_Disable
[....] Type 0x00d2  Location 0x46 AND(fe) OR(1)  BITFIELD: 0

그런 다음 CPU_Hyperthreading_Disable 토큰을 활성화하십시오.

# activateCmosToken 0x00d2 # CPU_Hyperthreading_Disable
[...] Type 0x00d2  Location 0x46 AND(fe) OR(1)  BITFIELD: 1

검증:

# isCmosTokenActive 0x00d1 # CPU_Hyperthreading_Enable
[...] Type 0x00d1  Location 0x46 AND(fe) OR(0)  BITFIELD: 0
# isCmosTokenActive 0x00d2 # CPU_Hyperthreading_Disable
[...] Type 0x00d2  Location 0x46 AND(fe) OR(1)  BITFIELD: 1

이제 큰 문제는이 기능을 적용하기 위해 단순히 재부팅해야하는지 아니면 전체 전원을 껐다 켜야하는지 여부입니다. 그것을 시도하고 어떻게되는지보십시오!


0

여기에서 Paul M이 제공 한 정보를 기반으로 다음과 같이 "스크립트"로 작성합니다.

fgrep , /sys/devices/system/cpu/cpu*/topology/thread_siblings_list |
cut -d, -f2 | sort -u |
sudo xargs -rI, sh -c 'echo 0 > /sys/devices/system/cpu/cpu,/online'

물론 그것은 하이퍼 스레딩을 BIOS와 땜질하는 것과 같은 의미로 끄지 않습니다 . 기본적으로 커널 작업 스케줄러에게 일부 코어를 사용하지 말라고 알려줍니다.

이전 상태 /proc또는 /sys하위 시스템을 기반으로 가정 한 소프트웨어는 여전히 최적화되지 않은 상태로 실행되거나이 런타임 변경으로 인해 실패 할 수 있으므로 재시작이 필요할 수 있습니다. 예를 들어, 나는 irqbalance그 상황에서 실패하기 쉽다 는 것을 알았습니다 .


0

HT 비활성화 :

echo 0 |sudo tee /sys/devices/system/cpu/cpu{4..7}/online

HT 활성화 :

echo 1 |sudo tee /sys/devices/system/cpu/cpu{4..7}/online

참고 : 이것은 하이퍼 스레딩을 실제로 비활성화하지는 않지만 거의 동일한 결과를 얻는 "가짜"코어를 비활성화합니다.


나는 당신이 사용하는 방식을 좋아 tee하지만 여전히 질문에 대한 진정한 대답을 제공하지 못합니다. 이러한 명령은 특정 하드웨어 구성에만 적용되며 다른 하드웨어 구성에 의도하지 않은 영향을 줄 수 있습니다. 그리고 그 명령에 대한 설명은 전혀 없습니다.
kasperd

0은 꺼져 있고 1은 켜져 있기 때문에 첫 번째 코어 4 개 (하이 스레딩을 사용하는 콴도 코어의 가짜 8 개)를 끄고 두 번째 코어를 다시 켜는 것을 이해하기 쉽다고 생각했습니다. 8 진수를 사용하는 경우 {8..15}
Zibri

0

오래된 주제이지만이 실험을 시도 할 이유가있었습니다. 첫째, 나는 런타임에 (약간 가짜) CPU를 비활성화하는 것이 부팅시 하이퍼 스레딩을 비활성화하는 것과 실제로 동일하다는 것을 확신하지 못한다. 즉, 우리 응용 프로그램에서 약간의 성능 향상을 보았습니다. (그러나 유지하기에는 충분하지 않습니다.)

사용 된 thread_siblings의 활성화를위한 키 / 비활성화로 값 (하이퍼 스레드 CPU를 공통)를 :

for i in /sys/devices/system/cpu/cpu[0-9]* 
do echo "$(cat $i/topology/thread_siblings) $i" 
done | 
awk '{v = (a[$1] ? 0 : 1); a[$1] = 1; print "echo " v " > " $2 "/online"}' | 
sudo sh 

최종 sudo sh 없이 명령을 시도하여 올바른지 확인하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.