Скомпилируйте и оптимизируйте для различных целевых архитектур

Полагаю, вы действительно хотите это:

$ echo -e "\tNA20826_NA20826\tNA20828_NA20828\tNA20819_NA20819" | sed -r '1s/_[^\t]*//g'
        NA20826 NA20828 NA20819

_[^\t]*, поскольку он TAB разделен, поэтому начиная с _ до TAB (или конца строки) можно быть удаленным.
g флаг должен заменить все вхождения в строке.
Первый 1 должен ограничить замену в первой строке - Строка заголовка.

Ваша собственная s команда ubstitude 's/[_].*$//', должна заменить от первого _ до конца строки, так что в итоге останется только один оставленный заголовок.

16
задан Georg Fritzsche 23 May 2010 в 02:06
поделиться

8 ответов

Если вы хотите, чтобы это работало чисто в Windows и в полной мере использовало 64-битные платформы дополнительных 1. адресного пространства и 2. регистров (вероятно, более полезных для вас), вы должны иметь по адресу как минимум, отдельный процесс для 64-битных.

Вы можете достичь этого, имея отдельный исполняемый файл с соответствующим заголовком PE64. Простое использование CreateProcess запустит это как соответствующую разрядность (если запущенный исполняемый файл не находится в каком-то перенаправленном месте, нет необходимости беспокоиться о перенаправлении папки WoW64

С учетом этого ограничения для Windows, вероятно, что просто «цепочка» к соответствующему исполняемому файлу будет самым простым вариантом для всех различных вариантов, а также упростит тестирование отдельного файла.

Это также означает, что вы «главный» Также вы можете «совместно использовать» одни и те же файлы для двух разных архитектур, если вы в настоящее время не чувствуете, что есть смысл использовать разные возможности.

Я бы предположил, что главный исполняемый файл может быть вынужден сделать определенный выбор, чтобы вы могли видеть, что происходит с «меньшими» версиями на более мощной машине (или какие ошибки возникают, если вы попробуете что-то другое).

Другие возможности, предоставляемые этой моделью:

  • Статическое связывание с различными версиями стандартных сред выполнения (с / без потоковой безопасности) и их использование соответствующим образом, если вы работаете без каких-либо возможностей SMP / SMT.
  • Определить, присутствуют ли несколько ядер и являются ли они реальными или гиперпоточными (а также знает ли ОС, как эффективно расписание в этих случаях).
  • проверка производительности таких вещей, как системный таймер / высокопроизводительные таймеры, и использование кода оптимизированы для этого поведения, скажем, если вы делаете что-либо, в течение которого вы ожидаете, что истечет определенное количество времени и, таким образом, можете узнать свою максимально возможную степень детализации.
  • Если вы хотите оптимизировать свой выбор кода на основе размера кеша / другой нагрузки на коробка. Если вы используете развернутые циклы, более агрессивные варианты развертывания могут зависеть от наличия определенного объема кеш-памяти уровня 1/2.
  • Условная компиляция для использования двойных / плавающих значений в зависимости от архитектуры. Менее важно для оборудования Intel, но если вы нацеливаетесь на определенный процессор ARM ' Некоторые из них имеют реальную аппаратную поддержку с плавающей запятой, а другие требуют эмуляции. Оптимальный код сильно изменится, даже если вы просто используете условную компиляцию, а не оптимизирующий компилятор (1).
  • Использование сопроцессорного оборудования, такого как видеокарты с поддержкой CUDA.
  • обнаруживает виртуализацию и изменяет поведение (возможно, пытается избежать записи в файловую систему)

Что касается выполнения этой проверки, у вас есть несколько вариантов, наиболее полезной для Intel является cpuid инструкция.

  • Окна
  • обнаруживает виртуализацию и изменяет поведение (возможно, пытается избежать записи в файловую систему)

Что касается выполнения этой проверки, у вас есть несколько вариантов, наиболее полезной для Intel является cpuid инструкция.

  • Окна
  • обнаруживает виртуализацию и изменяет поведение (возможно, пытается избежать записи в файловую систему)

Что касается выполнения этой проверки, у вас есть несколько вариантов, наиболее полезной для Intel является cpuid инструкция.

] В качестве альтернативы повторно внедрите / обновите существующий, используя доступную документацию по нужным вам функциям.

Достаточно много отдельных документов для разработки способов обнаружения вещей:

Большая часть того, за что вы будете платить в библиотеке CPU-Z, - это кто-то, кто делает все это (и связанные с этим мелкие неприятные проблемы) за вас.


  1. будьте осторожны с этим - трудно превзойти достойные оптимизирующие компиляторы на этом
5
ответ дан 30 November 2019 в 16:24
поделиться

Можете ли вы использовать скрипт?

Вы можете обнаружить процессор, используя скрипт, и динамически загрузить исполняемый файл, который наиболее оптимизирован для архитектуры. Он также может выбирать 32/64 битные версии.

Если вы используете Linux, вы можете запросить процессор с помощью

cat /proc/cpuinfo

. Возможно, вы могли бы сделать это с помощью скрипта bash / perl / python или хоста скриптинга windows в windows. Возможно, вы не хотите заставлять пользователя устанавливать скрипт-движок. Лучше всего подойдет тот, который работает на ОС из коробки.

На самом деле, в Windows вы, вероятно, захотите написать небольшое приложение на C #, чтобы вам было проще запрашивать архитектуру. Приложение C # может просто порождать любой исполняемый файл быстрее.

В качестве альтернативы вы можете поместить свои разные версии кода в DLL или общий объект, а затем динамически загружать их на основе обнаруженной архитектуры. Пока они имеют одинаковую подпись вызова, это должно работать.

6
ответ дан 30 November 2019 в 16:24
поделиться

Поскольку вы упоминаете, что используете GCC, я предполагаю, что ваш код написан на C (или C ++).

Нил Баттерворт уже предложил создать отдельные динамические библиотеки, но для этого нужны некоторые нетривиальные кроссплатформенные соображения (ручная загрузка динамических библиотек отличается в Linux, Windows, OSX и т. Д., И для ее правильной настройки, вероятно, потребуется некоторое время) .

Дешевое решение состоит в том, чтобы просто написать все ваши варианты, используя уникальные имена, и использовать указатель функции, чтобы выбрать правильный во время выполнения.

Я подозреваю, что дополнительная разыменование, вызванное указателем функции, будет амортизироваться фактической работой, которую вы делаете (но вы захотите это подтвердить).

Кроме того, для получения различных оптимизаций компилятора, вероятно, потребуются другие файлы .c / .cpp, а также некоторые изменения в вашем инструменте сборки. Но это, вероятно, менее общая работа, чем отдельные библиотеки (которые нуждались в этом уже в той или иной форме).

3
ответ дан 30 November 2019 в 16:24
поделиться

Позволяет разбить проблему на две составные части. 1) Создание зависимого от платформы оптимизированного кода и 2) сборка на нескольких платформах.

Первая проблема довольно проста. Инкапсулируйте зависимый от платформы код в наборе функций. Создайте разные реализации каждой функции для каждой платформы. Поместите каждую реализацию в отдельный файл или набор файлов. Для системы сборки проще всего, если вы поместите код каждой платформы в отдельный каталог.

Для второй части я предлагаю вам взглянуть на Gnu Atuotools (Automake, AutoConf и Libtool). Если вы когда-либо загружали и собирали программу GNU из исходного кода, вы знаете, что вам нужно запустить ./configure перед запуском make. Цель сценария конфигурирования состоит в том, чтобы: 1) убедиться, что ваша система имеет все необходимые библиотеки и утилиты, необходимые для сборки и запуска программы, и 2) настроить файлы Makefile для целевой платформы. Autotools - это набор утилит для генерации скрипта настройки.

Используя autoconf, вы можете создавать небольшие макросы для проверки того, что аппарат поддерживает все инструкции процессора, необходимые для вашего зависимого от платформы кода. В большинстве случаев макросы уже существуют, вам просто нужно скопировать их в скрипт autoconf. Затем automake и autoconf могут настроить файлы Makefile для загрузки соответствующей реализации.

Все это немного для создания примера здесь. Это займет немного времени, чтобы учиться. Но документация все там. Существует даже бесплатная книга , доступная онлайн. И этот процесс применим к вашим будущим проектам. Я думаю, что для поддержки мультиплатформенности это действительно самый надежный и простой способ. Многие предложения, опубликованные в других ответах, - это то, с чем работает Autotools (обнаружение процессора, поддержка статических и общих библиотек), и вам не нужно слишком много думать об этом. Единственная проблема, с которой вам, возможно, придется столкнуться, это выяснить, доступны ли автоинструменты для MinGW. Я знаю, что они являются частью Cygwin, если вы можете пойти по этому пути вместо этого.

1
ответ дан 30 November 2019 в 16:24
поделиться

Взгляните на liboil: http://liboil.freedesktop.org/wiki/ . Он может динамически выбирать реализации вычислений, связанных с мультимедиа, во время выполнения. Вы можете обнаружить, что можете использовать liboil, а не только его методы.

5
ответ дан 30 November 2019 в 16:24
поделиться

Да, это возможно. Скомпилируйте все ваши по-разному оптимизированные версии как разные динамические библиотеки с общей точкой входа и предоставьте исполняемую заглушку, которая загружается и запускается правильную библиотеку во время выполнения через точку входа, в зависимости от файла конфигурации или другой информации.

16
ответ дан 30 November 2019 в 16:24
поделиться

Поскольку вы не указали, есть ли у вас ограничения на количество файлов, я предлагаю другое решение: скомпилировать 5 исполняемых файлов, а затем создать шестой исполняемый файл, который запускает соответствующий двоичный файл. Вот какой-то псевдокод для Linux

int main(int argc, char* argv[])
{
    char* target_path[MAXPATH];
    char* new_argv[];
    char* specific_version = determine_name_of_specific_version();
    strcpy(target_path, "/usr/lib/myapp/versions");
    strcat(target_path, specific_version);

    /* append NULL to argv */
    new_argv = malloc(sizeof(char*)*(argc+1));
    memcpy(new_argv, argv, argc*sizeof(char*));
    new_argv[argc] = 0;
    /* optionally set new_argv[0] to target_path */

    execv(target_path, new_argv);
}

С другой стороны, этот подход позволяет прозрачно предоставлять пользователю как 32-битные, так и 64-битные двоичные файлы, в отличие от любых предложенных библиотечных методов. С другой стороны, в Win32 нет execv (но хорошая эмуляция в cygwin); в Windows вам нужно создать новый процесс, а не повторно запускать текущий.

3
ответ дан 30 November 2019 в 16:24
поделиться

Вы упомянули компилятор Intel. Это забавно, потому что по умолчанию он может делать что-то подобное. Однако есть загвоздка. Компилятор Intel не вставлял проверки на соответствующую функциональность SSE. Вместо этого они проверили, есть ли у вас конкретный чип Intel. По-прежнему будет медленный случай по умолчанию. В результате процессоры AMD не получат подходящих версий, оптимизированных для SSE. Есть хаки, которые заменят проверку Intel на правильную проверку SSE.

Разница в 32/64 бита потребует двух исполняемых файлов. И формат ELF, и формат PE хранят эту информацию в заголовке исполняемых файлов. По умолчанию запустить 32-битную версию несложно, проверьте, используете ли вы 64-битную систему, а затем перезапустите 64-битную версию.

1
ответ дан 30 November 2019 в 16:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: