Nano Hash - криптовалюты, майнинг, программирование

Почему выполнение большего количества инструкций по сборке Pentium занимает меньше времени?

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

Результаты, которые мы получаем на двух машинах Intel, очень разные.

Инструкция CPUID сообщает о семействе, модели и шаге.

Машина 1: Семейство 6, Модель 15 Степпинг 11. CPUZ сообщает "Intel Core 2 Duo E6750"
Инструкции выполняются со статистически одинаковой скоростью.

Машина 2: Семейство 15, Модель 3, Степпинг 3. CPUZ сообщает "Intel Pentium 4"
Первая последовательность занимает примерно 8% больше времени, чем вторая.

Мы просто не можем объяснить увеличение времени. Не должно быть никаких других задержек флагов, предсказания ветвей, проблем с использованием регистров и т. Д. По крайней мере, то, что мы можем сказать.

Кто-нибудь знает, почему выполнение первой последовательности на одной машине занимает больше времени?

Изменить: добавление «XOR PTR ereg, 0» к первой последовательности приводит к совпадению синхронизации со второй на Pentium 4. Любопытно.

Первая последовательность:

00000040               ALUSHIFT_AND_C_V_E LABEL NEAR
00000040  0F B7 04 55       MOVZX   EAX, gwr[(SIZEOF WORD) * EDX]       ; EAX = 0000000000000000 LLLLLLLLLLLLLLLL
   00000000 E
00000048  0F B7 14 4D       MOVZX   EDX, gwr[(SIZEOF WORD) * ECX]       ; EDX = 0000000000000000 RRRRRRRRRRRRRRRR
   00000000 E
00000050  23 C2             AND     EAX, EDX                            ; AX = L&R      (result)
00000052  A3 00000000 E     MOV     dvalue, EAX                         ; Save the temporary ALU/Shifter result
00000057  C3                RET                                         ; Return

Вторая последовательность:

00000060               ALUSHIFT_AND_C_V_NE LABEL NEAR
00000060  0F B7 04 55       MOVZX   EAX, gwr[(SIZEOF WORD) * EDX]       ; EAX = 0000000000000000 LLLLLLLLLLLLLLLL
   00000000 E
00000068  0F B7 14 4D       MOVZX   EDX, gwr[(SIZEOF WORD) * ECX]       ; EDX = 0000000000000000 RRRRRRRRRRRRRRRR
   00000000 E
00000070  23 C2             AND     EAX, EDX                            ; AX = L&R      (result)
00000072  80 35 00000000 E  XOR     BYTE PTR ereg, 1                    ; E = ~E
   01
00000079  A3 00000000 E     MOV     dvalue, EAX                         ; Save the temporary ALU/Shifter result
0000007E  C3                RET                                         ; Return
08.07.2009

  • Похоже на вопрос, который я задал: stackoverflow.com/questions/688325/ 08.07.2009
  • являются ALUSHIFT_AND_C_V_E LABEL NEAR и ALUSHIFT_AND_C_V_NE LABEL NEAR эти две последовательности? Если это так, вам, вероятно, следует поместить их в отдельные блоки, чтобы код было легче читать. 08.07.2009
  • Также было бы неплохо знать, о каких процессорах мы говорим (человеческими именами, а не строками CPUID). 08.07.2009
  • @Mark: Спасибо за это. Я начал расследование, основываясь на некоторых полученных вами ответах. @jalf: Я отредактировал, чтобы включить ваши отличные предложения. 08.07.2009

Ответы:


1

После Pentium I или II большая часть оптимизаций, выполняемых компилятором, не была необходимой. Чип разложит эти инструкции на микрооперации, а затем оптимизирует их для вас. Это может быть разница в предсказании переходов между чипами или тот факт, что XOR + RET так же дорого, как и простой RET. Я не так хорошо знаком с тем, какие модели Pentium вы смотрите выше, чтобы сказать. Другая возможность заключается в том, что это также может быть проблема со строкой кеша или разница в оборудовании.

Что-то может быть в документации Intel, а может и нет.

Несмотря ни на что. Опытные программисты на ассемблере знают, что единственная истина достигается посредством тестирования, которым вы и занимаетесь.

08.07.2009
  • Кодирование Pentium и выше - это такое же вуду, как и все остальное. Иногда добавление дополнительных инструкций ускоряет работу и т. Д. Фактическое тестирование и выбор времени - единственный путь! 08.07.2009

  • 2

    Оказывается, есть какое-то любопытное взаимодействие с тем, где расположен код, который вызывает увеличение. Несмотря на то, что все выровнено с кешем, переключение блоков кода привело к увеличению времени на Pentium-4.

    Спасибо всем, кто нашел время исследовать это или посмотреть на это.

    10.07.2009

    3

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

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

    Настройка и тестирование - вот что действительно дает производительность в конечном итоге, даже если вы не понимаете почему. Хотя как только вы переместите этот код на старую микросхему или новую микросхему, или другую материнскую плату, или то же семейство микросхем, но с другим степпингом, все ваши настройки производительности могут вам помочь.

    13.07.2009

    4

    Несколько месяцев назад со мной произошло нечто подобное. В моем проекте есть переключатель конфигурации для включения использования __thread для локальных переменных потока. Без него он использовал бы pthread_getspecific и тому подобное. Последняя выполняет столько же, сколько и версия __thread плюс вызов функции плюс некоторые дополнительные инструкции по настройке аргументов, сохранению регистров и так далее. Интересно, что более трудоемкая версия всегда была быстрее. Но только на Pentium 4. Все остальные фишки вели себя вменяемо.

    06.08.2009
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..