Я могу дать лишь несколько общий ответ, но, надеюсь, он укажет вам правильное направление.
Вы не сказали, какую x86-плату вы используете, но в недревних системах шина ISA будет находиться за мостом PCI-to-ISA. Вы можете использовать lspci
, чтобы найти этот мост. Мост обеспечивает сопоставление основной памяти и пространства ввода-вывода с памятью шины ISA и пространством ввода-вывода. Это устанавливается ядром при загрузке в соответствии с информацией, указанной в BIOS, а именно ACPI, включая устаревший PNP. Вы можете увидеть информацию об этом процессе в dmesg
после загрузки.
Даже в современной системе все еще есть устаревшие устройства ISA, хотя теперь они подключены к шине LPC, а не к реальной шине ISA.Драйверы ядра Linux для такого устройства, т. е. драйвер клавиатуры/мыши 8042 PS/2 (см. drivers/input/serio
), затем резервируют необходимые им порты (request_region
) при инициализации ( i8042_platform_init
в i8042-io.h
), освободить их при выходе и перенаправить ввод-вывод (inb
, outb
и т. д. ) общаться с ним. Я не знаю, как это работает для доступа к памяти, но, вероятно, похоже. Зарезервированные порты отображаются в /proc/ioports
.
Мост должен отображаться в /sys/bus/pci/devices
, возможно, там вы найдете дополнительную информацию. Также есть /sys/bus/isa
, но я не уверен, при каких обстоятельствах ядро будет заполнять его информацией.
Итак, сначала я бы попробовал проверить, реагирует ли плата на некоторые порты ввода/вывода. Также попробуйте процедуру перечисления PNP (или проверьте dmesg
, если это еще не сделано при загрузке), если она отвечает на это, остальное будет намного проще.
Наконец, я бы попытался выяснить, как ваш мост PCI-to-ISA отображает пространство памяти, какие операции ядра вам нужны, чтобы зарезервировать это пространство памяти, а затем вы можете снова проверить его и посмотреть, не произойдет ли что-нибудь.
Правка:
В книге Linux Device Drivers, 3rd edition есть некоторая информация о доступе к памяти ISA в разделе 9.4.5.
Изменить:
Что попробовать:
1) Загрузитесь с lilo
вместо grub
, включите "дыру" (ISA-mapping) в BIOS , посмотрите, загружается ли он. Да, lilo
все еще работает.
2) Погуглите VIA VT82C686A South Bridge
техпаспорт. В пространстве конфигурации PCI, если мост PCI-to-ISA, есть следующий регистр:
Offset 43 - ROM Decode Control
Setting these bits enables the indicated address range to be
included in the ROMCS# decode:
7 FFFE0000h-FFFEFFFFh
6 FFF80000h-FFFDFFFFh
5 000E8000h-000EFFFFh
4 000E0000h-000E7FFFh
3 000D8000h-000DFFFFh
2 000D0000h-000D7FFFh
1 000C8000h-000CFFFFh
0 000C0000h-000C7FFFh
Так что, я думаю, вы можете попробовать включить «дыру» (отображение ISA) после загрузки и проверить с помощью логического анализатора, работает ли он. Также стоит попробовать использовать FFFE0000h
вместо 000E0000h
, если карта не декодирует старшие биты.
Я не знаю, как правильно это сделать и сообщить ядру Linux об изменении отображения. Может быть, есть также варианты загрузки для этого.
Я знаю, что вы можете получить доступ к конфигурационному пространству PCI через псевдофайл /sys/bus/pci/devices/0000:00:07.0/config
, так что вы даже можете попробовать это вне ядра Водитель.
3) Обязательно проверьте dmesg
и /sys/bus/pnp
, чтобы убедиться, что ваша карта уже выполняет перечисление. Если вы не можете понять вывод dmesg
, поместите его в pastebin и опубликуйте ссылку; Я могу посмотреть.
Попробуйте использовать grep
.
(
export LC_ALL=C
grep -E '^(BL|FR|[GMTW]F|GP|M[CQ]|NC|PM|RE|YT)([^|]*\|){19}TRUE(\||$)' |
cut -d'|' -f1-3,6,10,11,13,19,20
)
Как предложил @don_crissti, и предполагая, что все строки содержат не менее 20 полей, вы также можете попробовать сначала вырезать, что в зависимости от количества и длины полей в каждой строке и доли совпадающих строк может дать лучшую производительность:
(
export LC_ALL=C
cut -d'|' -f1-3,6,10,11,13,19,20 |
grep -xE '(BL|FR|[GMTW]F|GP|M[CQ]|NC|PM|RE|YT).*\|TRUE'
)
Приведенный ниже сценарий возвращает произвольный набор столбцов в вашей строке, если первый столбец равен определенной строке. И требуемое соответствие, и возвращаемые столбцы являются аргументами для запуска скрипта. Пример:
python3 /path/to/script.py /path/to/file.txt monkey 3 12 > output.txt
возвращает столбцы 0, 2 и 11 (первый столбец - 0) строки в файле file.txt, если первый столбец равен "monkey"
На файле размером 30.000.000 строк и объемом несколько гигабайт скрипт выполнил работу менее чем за минуту на моем более чем 10-летнем компьютере. Поскольку скрипт читает и обрабатывает по строке, мы можем предположить, что потребляемое время более или менее линейно, и скрипт выполнит работу значительно быстрее, чем ваша команда.
#!/usr/bin/env python3
import sys
s = sys.argv[2]; cols = [int(n) for n in sys.argv[3:]]
with open(sys.argv[1]) as src:
for l in src:
l = l.split("|"); match = l[0].strip()
if match == s:
print(match, " ".join(list(l[i].strip() for i in cols)))
get_cols.py
Запустите его со следующими аргументами:
Например:
python3 /path/to/get_cols.py Germany 2 12 > output.txt
Вот и все
Вы могли бы хотя бы избавиться от сокращения
:
awk -F '|' 'BEGIN { OFS=FS } $20 == "TRUE" && /^(BL|FR|GF|GP|MC|MF|MQ|NC|PF|PM|RE|TF|WF|YT)/ { print $1,$2,$3,$6,$10,$11,$13,$19,$20 }' indata >outdata
Я не знаю, работает ли это быстрее, но это позволяет избежать разделения каждой строки на поля как минимум дважды.
Вы также можете попробовать сначала вырезать правильные столбцы (чтобы сократить работу awk
до простой фильтрации):
cut -d '|' -f 'columnspec' indata | awk -F '|' 'BEGIN { OFS=FS } $20 == "TRUE" && /^(BL|FR|GF|GP|MC|MF|MQ|NC|PF|PM|RE|TF|WF|YT)/ { print }' >outdata
Другой подход - разделить файл на управляемые части, фильтровать их параллельно , а затем объедините результат. См. Руководство для split
в вашей системе Unix. Возможно, вам придется использовать флаг -a
с разделением, если вы генерируете много сотен файлов, но я бы рекомендовал подсчитать количество строк в файле данных и разделить примерно на 10 файлов. .
Попробовать мок? Используйте версию 1.34 или выше. Возможное ускорение задачи, обрабатывающей большой файл, может быть 8-кратным в примере некоторых людей:
Чтобы провести абсолютное сравнение с вашей текущей производительностью, эта задача заняла 1 минуту (с mawk) для обработки 1 ГБ. Попытка использовать код Java (JIT) была не быстрее.
Кроме того, производительность многих утилит снизилась после добавления поддержки UTF-8. поиск в Google предполагает, что это может очень сильно повлиять по крайней мере на некоторые версии awk: попробуйте запустить с переменной окружения LC_ALL=C
(например, LC_ALL=C awk...
).