#linux #awk #s390x
Вопрос:
По сути, я хочу извлечь размер кэша L3 в байтах из lscpu. Сложность заключается в том, что единицы измерения, используемые lscpu, не согласованы между версиями, и то, что мне нужно, должно работать со всеми версиями (включая версии до того, как была доступна опция —bytes). lscpu из того, что я вижу, будет использовать либо K, KiB, M, либо MiB, так что это то, что я пытаюсь проанализировать.
Вот что выводит lscpu:
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 16
On-line CPU(s) list: 0-15
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 16
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 60
Model name: Intel Core Processor (Haswell, no TSX, IBRS)
Stepping: 1
CPU MHz: 2299.998
BogoMIPS: 4599.99
Virtualization: VT-x
Hypervisor vendor: KVM
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 4096K
L3 cache: 16384K
NUMA node0 CPU(s): 0-15
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology eagerfpu pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm invpcid_single ssbd ibrs ibpb tpr_shadow vnmi flexpriority ept vpid fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt arat md_clear spec_ctrl
И это то, что у меня есть до сих пор, но, похоже, я не могу с этим покончить.
$ lscpu | awk '/L3 cache:/{print $3$4;next};/(M|MiB)$/{printf "%un", $3*(1024*1024);next};/(K|KiB)$/{printf "%un", $3*1024;next}'
0
32768
32768
4194304
16384K
Есть идеи, как настроить мою команду awk, чтобы это сработало?
Редактировать: Мой ожидаемый результат будет просто:
16777216
Комментарии:
1. @anubhava обновленный вопрос
2.
16777216
был бы вывод, если бы вход был16384KiB
, но это не так, это16384K
так, и поэтому вывод должен быть16384000
, так как 1 КБ равно 1000, а 1 КБ равно 1024. Видишь en.wikipedia.org/wiki/Binary_prefix .
Ответ №1:
На самом деле ответ Сайруса является оптимальным, но если вы настроены на awk, попробуйте это:
awk -F: 'BEGIN{def=1024}/^L3/{if($2~/M/){def=def*def}; printf "%un", $2*def}'
Комментарии:
1. Похоже, это именно то, что мне нужно. Не смог использовать решение от Сайруса, оставил подробную информацию о том, почему в ответе на комментарий. Спасибо!
2. 1 вопрос, который у меня есть, заключается в том, какова цель использования gsub здесь? Быстрое тестирование без него, похоже, ничего не меняет, и я действительно не могу понять, что он делает
3. Ну, я просто хочу убедиться, что awk не пытается умножить M или K …
4. По — видимому, это не беспокоит awk, если есть конечные альфы =}
5. Правильно, при выполнении любой числовой операции awk просто игнорирует каждый символ, начиная с первого, который он может распознать как не являющийся частью числа. кстати
def=def*def
=def*=def
Ответ №2:
Получите кэш 3-го уровня (L3) в байтах:
getconf LEVEL3_CACHE_SIZE
Комментарии:
1. getconf нельзя использовать, так как он, по-видимому, извлекает информацию,
/sys/devices/system/cpu/cpu0/cache/
которая является неполной в некоторых архитектурах ОС (в частности, RHEL s390x), поэтому он просто возвращает 0. lscpu извлекает информацию из других источников, чтобы она могла давать значения
Ответ №3:
$ cat tst.awk
BEGIN {
mult["K"] = 1000
mult["KiB"] = 1024
mult["M"] = mult["K"]^2
mult["MiB"] = mult["KiB"]^2
}
sub(/^L3 cache:/,"") {
smbl = $NF
sub(/[^[:alpha:]] /,"",smbl)
print $0 * mult[smbl]
}
$ awk -f tst.awk file
16384000