Зачем программе требуется определенное минимальное количество ядер ЦП?

55

Можно ли написать код (или законченное программное обеспечение, а не кусок кода), который не будет работать должным образом при запуске на процессоре с числом ядер менее N? Без явной проверки и намеренного сбоя:

ЕСЛИ (noOfCores <4) ТОГДА не работают должным образом специально

Я смотрю на минимальные системные требования игры ( Dragon Age: Inquisition ), и в ней указан минимум четырехъядерный процессор. Многие игроки говорят, что он НЕ работает на двухъядерных процессорах и даже на Intel Core i3 с двумя физическими и двумя логическими ядрами. И это НЕ проблема вычислительной мощности.

Насколько я понимаю, потоки полностью изолированы от процессора операционной системой, поскольку это невозможно.

Просто чтобы прояснить ситуацию:

Я НЕ спрашиваю: «Могу ли я узнать количество ядер ЦП из кода и умышленно выйти из строя?» ... Такой код был бы злонамеренным (заставляет вас покупать более дорогой процессор для запуска программы - без необходимости в вычислительных ресурсах). Я спрашиваю, что ваш код, скажем, имеет четыре потока и дает сбой, когда два потока выполняются на одном физическом ядре (без явной проверки системной информации и преднамеренного сбоя) .

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

uylmz
источник
11
Если вы внимательно прочитаете мой вопрос, вы увидите, что они не задают одно и то же.
uylmz
21
Поскольку число ядер может быть восстановлено, его можно сравнить с N, и если это сравнение оценивается как истинное, код может делать все, что ему, черт возьми, нужно, включая, но не ограничиваясь, поведение, которое не рекламируется. Каков твой вопрос?
3
Вы уверены, что проблема действительно и напрямую связана с количеством ядер? Может быть, упомянутая игра частично основана только на функции (правильно), предоставляемой процессором, по крайней мере, с 4 ядрами?
mgoeminne
25
Обратите внимание, что «минимальные системные требования» часто являются «минимальными системными требованиями для работы с приемлемой производительностью», особенно в играх. Вполне возможно, что Dragon Age теоретически мог бы работать на одном ядре, но если бы вы сделали это, это показало бы массивные падения кадров. Поэтому им требуется такое количество ядер, чтобы не заставлять вас покупать аппаратное обеспечение, а избегать жалоб на качество со стороны пользователей более дешевого оборудования.
Gort the Robot
3
@Sebb: я думаю, что вы на что-то: если 4 физических ядра коррелируют с наличием большего объема кеша, чем 2 физических / 4 логических, то игра, естественно, захлебывается на машинах 2x2, не выходя за пределы их вычислительной мощности, потому что отсутствует кеш все время. Тест состоял бы в том, чтобы найти процессор с 2x2 ядрами и загрузкой кеша или 4 ядра с небольшим кешем, и посмотреть, что получится.
Стив Джессоп

Ответы:

45

Может быть возможно сделать это "случайно" с небрежным использованием основного сродства. Рассмотрим следующий псевдокод:

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

Если вы запустите четыре из них на двухъядерном процессоре, то либо с настройкой привязки к ядру что-то пойдет не так, либо вы получите два потока, переключающие доступные ядра, и два потока, которые никогда не планируются. Ни в коем случае он прямо не спросил, сколько всего ядер.

(Если у вас есть долго работающие потоки, настройка соответствия процессоров обычно улучшает пропускную способность)

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

Изменить: этот пост получил 33 голосов, что довольно много, учитывая, что оно основано на догадках!

Кажется, что у людей есть DA: я плохо работаю на двухъядерных системах: http://www.dsogaming.com/pc-performance-analyses/dragon-age-inquisition-pc-performance-analysis/ Этот анализ упоминает, что ситуация значительно улучшается, если включена гиперпоточность. Учитывая, что HT больше не добавляет единицы выдачи инструкций или кеш, он просто позволяет одному потоку работать, пока другой находится в стойке кеша, что говорит о том, что он связан исключительно с числом потоков.

Другой автор утверждает, что смена графических драйверов работает: http://answers.ea.com/t5/Dragon-Age-Inquisition/Working-solution-for-Intel-dual-core-CPUs/td-p/3994141 ; учитывая, что графические драйверы, как правило, жалкий улей мрази и подлости, это не удивительно. Один печально известный набор драйверов имел режим «правильный и медленный» по сравнению с «быстрым и неправильным», который был выбран при вызове из QUAKE.EXE. Вполне возможно, что драйверы ведут себя по-разному для разного количества видимых процессоров. Возможно (вернемся к размышлениям) используется другой механизм синхронизации. Злоупотребление спин-замками ?

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

Редактирование 2: в комментариях упоминается, что ОС пытается избежать истощения потоков. Обратите внимание, что в игре может быть свой собственный внутренний квази-планировщик для распределения работы между потоками, и в самой видеокарте будет аналогичный механизм (который фактически является собственной многозадачной системой). Вероятность ошибки в одном из тех или взаимодействия между ними довольно высоки.

www.ecsl.cs.sunysb.edu/tr/ashok.pdf (2008) - дипломная работа по улучшению планирования для графических карт, в которой явно упоминается, что они обычно используют планирование «первым пришел - первым обслужен», что легко реализовать в не упреждающие системы. Ситуация улучшилась? Возможно нет.

pjc50
источник
1
Да, ответ на этот вопрос состоит из двух частей: привязка к процессору позволяет запрограммировать что-то, что сделает это техническим требованием в Windows, альтернативный ответ - системы реального времени могут определенно требовать таких вещей. +1 за то, что он единственный, кто упомянул сходство с процессором, что действительно является наиболее вероятным виновником того, о чем здесь говорят.
Джимми Хоффа
3
Что может пойти не так, если вы установите привязку к текущему ядру? С преимущественной многозадачностью ожидающий поток будет запланирован, если текущий не имеет максимально возможного приоритета («в реальном времени» в Windows). Я бы увидел другой сценарий: каждому из 4 потоков назначается статически определенная привязка 1,2,4,8, и в этом случае последние два потока никогда не будут запланированы (хотя я не уверен, если установить привязку к эффективной ноль будет успешным).
Руслан
@Ruslan Может быть, попытка установить недействительное сходство приведет к краху приложения?
Луан
1
@ Луаан, это не та рискованная операция, которая может привести к аварии. Максимум, что я ожидаю, это ошибка, возвращаемая ОС. Я только что проверил, в Linux я получаю ошибку "Неверный аргумент". Не знаю, что скажет Windows.
Руслан
@Ruslan. Каждая крупная ОС на протяжении более десяти лет включала код, позволяющий избежать истощения потоков (обычно путем повышения приоритета потока после того, как он не работал достаточно долго).
Во
34

Может быть необходимо иметь 4 ядра, потому что приложение выполняет четыре задачи в параллельных потоках и ожидает, что они завершатся почти одновременно.

Когда каждый поток выполняется отдельным ядром и все потоки имеют одинаковую вычислительную нагрузку, они вполне вероятно (но далеко не гарантированы) завершить примерно в одно и то же время. Но когда два потока работают на одном ядре, время будет намного менее предсказуемым, потому что ядро ​​будет постоянно переключать контекст между двумя потоками.

Ошибки, возникающие из-за непредвиденной синхронизации потоков, называются « состояниями гонки ».

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

Обратите внимание, что программная архитектура, которая зависит от независимых потоков, работающих с определенным временем, является чрезвычайно хрупкой и признаком очень плохого понимания параллельного программирования. Практически во всех многопоточных API имеются функции, позволяющие явно синхронизировать потоки для предотвращения подобных проблем.

Philipp
источник
11
Но любая игра имеет хрупкую зависимость от возможности завершить все вычисления для следующего кадра вовремя, чтобы воспроизвести его с разумной частотой. Даже если ваши 4 потока синхронизированы правильно, своевременное рендеринг может оказаться невозможным, и нет никакой выгоды в игре, которая является вычислительно правильной, но не воспроизводимой из-за задержки и заикания.
бесполезно
1
@Useless: Это не совсем так. Например, вы можете буферизовать кадры или данные моделирования, чтобы скрыть заикание, и есть параллельные проекты, которые являются более согласованными. Выполнение всей вашей обработки в X раз и требование точной синхронизации этой обработки - разные вопросы.
DeadMG
23
«Архитектура программного обеспечения, которая зависит от независимых потоков, работающих с определенным временем, чрезвычайно хрупка». Именно поэтому я не могу представить себе игру, которая вообще не работает с 2 ядрами, но надежно работает с 4 ядрами. Даже с четырьмя ядрами время будет непредсказуемым, поэтому условия гонки также могут возникнуть, даже если и реже.
свик
8
@ свик конечно. Но вопрос спрашивает "возможно ли это?" не "это нормально?"
user253751
5
Любой код с такого рода «условиями гонки» просто сломан , независимо от того, на скольких ядрах вы его запускаете. (Тем более, что нет абсолютно никаких гарантий относительно того, что еще работает в системе.) Я серьезно сомневаюсь, что это будет причиной, учитывая, насколько легко это может привести к отключению игры даже в системе hexacore ...
DevSolar
16

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

Одним из важных показателей производительности игры является частота кадров. Обычно они работают со скоростью 30 или 60 кадров в секунду. Это означает, что игровой движок должен визуализировать текущий вид из игрового состояния за фиксированное время. Чтобы достичь 60 кадров в секунду, для этого требуется чуть более 16 мсек. Игры с высококачественной графикой чрезвычайно сильно нагружены процессором, поэтому между попыткой добиться более высокого качества (что занимает больше времени) и необходимостью оставаться в этом временном бюджете существует огромная отдача. Таким образом, бюджет времени для каждого кадра чрезвычайно ограничен.

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

Вы можете, теоретически, втиснуть все это в одно ядро, но тогда все станет намного сложнее. Внезапно вы должны убедиться, что все эти состояния игры происходят достаточно быстро и позволяют вашему рендерингу происходить. Вы не можете просто сделать их двумя программными потоками, потому что нет способа заставить ОС понять: «Поток A должен выполнить X работы за 16 мсек независимо от того, что делает поток B».

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

Горт Робот
источник
Хотя это действительно так, бывает, что вы можете купить двухъядерное оборудование, достаточно мощное, чтобы оно могло достичь большего за данный период времени, чем четырехъядерное оборудование, описанное в минимальных спецификациях. Почему поставщик не может назвать такое оборудование приемлемым, решение, которое может только потерять его продажи?
Жюль
4
Сравнение не 2 против 4 ядер. По сути, это 1 против 3 ядер, поскольку ЦП № 0 будет в значительной степени привязан графическим драйвером и ЦОД. Существуют также значительные эффекты кэширования и миграции, если вы переподписываете ЦП несколькими задачами в типичной системе задач современной игры. Требование существует, потому что Frostbite (двигатель DA: I) разработан с нуля с очень тщательной настройкой, которая требует определенного количества ядер.
Ларс Виклунд
6
@LarsViklund Похоже, вы знаете больше деталей, чем кто-либо еще здесь. Рассматривали ли вы собрать ответ вместе?
Gort the Robot
1
«Маловероятно, что эти« минимальные требования »представляют собой нечто, ниже которого игра не будет запускаться. Гораздо более вероятно, что они представляют собой нечто, ниже которого игра не будет работать с приемлемой производительностью». - Intel G3258 - это очень мощный двухъядерный процессор, широко используемый геймерами, способный запускать игры, равные или более ресурсоемкие, чем Dragon Age Inquisition, но многие игроки сообщают, что игра на нем не запускается.
uylmz
2
@ Reek Я сомневаюсь, что конечный пользователь может легко сказать, насколько ресурсоемкая конкретная игра по сравнению с другой.
Gort the Robot
9

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

Очевидно, что если потоки реального времени ждут чего-то, что не позволяет им спать (например, спин-блокировки), разработчик программы облажался.

Джошуа
источник
1
Возможно, когда пользовательское приложение сначала запрашивает потоки в реальном времени, дизайнер облажался: D
Luaan
2
Я сделал это. Полмиллиона строк кода. В одном случае используется около 300 строк. Поток реального времени тратит большую часть своего времени на ожидание ввода, поэтому он может пометить время ввода и передать его потоку с меньшим приоритетом.
Джошуа
2
@Luaan Для большинства приложений я бы с тобой согласился, но игры - это другой зверь, как и встроенные приложения. В обоих этих случаях забота о хорошей игре с другими параллельными приложениями в основном не учитывает производительность.
Рейраб
Хотя он не будет особенно эффективным, этот сценарий не приведет к каким-либо тупикам - об этом позаботится инверсия приоритетов (при условии, что на полпути приличный планировщик в любой крупной ОС последнего десятилетия)
Voo
2
@Joshua > Windows не знает, что такое инверсия приоритетов. Какая? support.microsoft.com/kb/96418 , msdn.microsoft.com/en-us/library/windows/desktop/ms684831.aspx . Кроме того, инверсия приоритетов - это термин, который описывает проблему , а не решение (@Voo).
Боб
3

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

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

DJ Bazzie Wazzie
источник
Этот. Помните, что высказывание «не проверяйте ядра» означает, что компания разрабатывает свой программный продукт особым образом, чтобы заставить пользователей покупать более дорогое оборудование (что было бы злонамеренно).
uylmz
2
Эти проблемы существуют, пока есть компьютерные игры. Вначале у нас было 486dx и 486sx, позже Pentium MMX и не MMX, ядро ​​и не ядро, и сегодня у нас есть требования к n-ядру. Это одна из причин, почему консоли все еще существуют.
DJ Bazzie Wazzie
4
У вас есть справочник по играм, которые занимаются планированием процессора сами? Насколько я знал, это не возможно напрямую под Windows, по крайней мере, не так, как вы предлагаете.
Жюль
2
@djbazziewazzie на самом деле Windows действительно предоставляет API для этого, то есть установить поток, чтобы всегда использовать одно и то же ядро; это называется привязкой к потоку и не позволяет вам вручную выбирать, какой фрагмент кода выполняется, где и когда, и не может вызвать системный сбой, как вы предлагаете (система проигнорирует запрос на установку соответствия для несуществующего ядра, и . просто держать планирования нить любого ядра , когда она становится доступной , я уверен , что это то , что идентификатор Tech использует, и это на самом деле не составит «управление самого оборудования темы».
Жюль
1
@djbazziewazzie Похоже, вы также неправильно поняли смысл Grand Central Dispatch, который не дает разработчикам больше контроля над тем, как их код распределяется по ядру; на самом деле, его цель с точностью до наоборот: выбор того, сколько потоков создавать и какой код должен выполняться на каком потоке из рук приложений, чтобы его можно было оптимизировать для доступного оборудования на уровне всей системы. Зависимость от наличия определенного количества ядер - это именно та проблема, которую GCD должен был предотвратить.
Жюль
1

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

Другими словами, невозможно написать программное обеспечение, которое всегда останавливается на менее чем N ядрах.

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

Lawtonfogle
источник
1

Возможно, что три потока что-то делают (генерируют фон или генерируют движение NPC) и передают события четвертому, который должен агрегировать / фильтровать события и обновлять модель представления. Если четвертый поток не получает все события (потому что он не запланирован на ядре), тогда модель представления не обновляется правильно. Это может происходить только время от времени, но эти ядра должны быть доступны в любой момент. Это может объяснить, почему вы не видите высокой загрузки ЦП все время, но игра все равно не работает должным образом.

TMN
источник
1
В таком сценарии игра также может случайно выйти из строя, когда запланированы запуск фоновых служб, что довольно часто на большинстве ПК.
Жюль
1

Я думаю, что Иисус Навин идет по правильному пути, но не до конца.

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

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

Лорен Печтель
источник
Обычно невозможно написать поток, который не уступит управление другим потокам. Все современные не-ОСРВ операционные системы используют вытесняющую многозадачность, что преднамеренно делает невозможным для потока (пользовательского режима) контроль над данным ядром. Потоки ядра, конечно, другое дело.
Рейраб
@reirab Повышение приоритета.
Лорен Печтел
@Loren Не меняет того факта, что планировщик все еще умирает, это означает, что вы должны делиться временем с другими потоками с таким же приоритетом, а планировщик повышает приоритет голодных потоков. Вы не можете сделать это на обычных ОС, и даже если бы вы могли, игры, безусловно, не были бы приемлемым приложением для этого.
Во
1

Is it possible to write code (or complete software, rather than a piece of code) that won't work properly when run on a CPU that has less than N number of cores?

Абсолютно. Использование потоков в реальном времени было бы хорошим примером ситуации, в которой это не только возможно, но и является желательным (и часто единственным правильным) способом выполнения работы. Однако потоки реального времени обычно ограничиваются ядром ОС, обычно для драйверов, которые должны быть в состоянии гарантировать, что какое-либо аппаратное событие обрабатывается в течение некоторого определенного периода времени. Вы не должны иметь потоков в реальном времени в обычных пользовательских приложениях, и я не уверен, что даже возможно иметь потоки в приложении пользовательского режима Windows. Как правило, операционные системы преднамеренно делают это невозможным именно из земли пользователя, потому что это позволяет конкретному приложению взять на себя управление системой.

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

reirab
источник
1

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

Представьте, например, поток производителя, отправляющий задачи в очередь, которая обслуживает 4 потока потребителя. Есть только два ядра:

Производитель пытается получить спин-блокировку, но она удерживается потребителем, работающим на другом ядре. Два ядра работают в режиме блокировки, пока производитель вращается, ожидая снятия блокировки. Это уже плохо, но не так плохо, как получится.
К сожалению, потребительский поток находится в конце своего кванта времени, поэтому он выгружается, и запланирован другой потребительский поток. Он пытается завладеть блокировкой, но, конечно, блокировка взята, поэтому теперь два ядра вращаются и ожидают чего-то, что не может произойти.
Поток производителя достигает конца своего временного интервала и прерывается, просыпается другой потребитель. Опять же, два потребителя ждут освобождения блокировки, и этого не произойдет, пока не пройдут еще два кванта времени.
[...] Наконец, потребитель, который держал спинлок, снял блокировку. Это немедленно взято, кто бы ни вращался на другом ядре. С вероятностью 75% (от 3 до 1) это еще один потребительский поток. Другими словами, вероятность того, что производитель все еще застопорился , составляет 75% . Конечно, это означает, что потребители тоже останавливаются. Без заданий производителя, им нечего делать.

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

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

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

Если я понимаю, что вы спрашиваете, это возможно, но это очень, очень плохо.

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

Эта зависимость между временем и правильностью - это то, что информатика называет состоянием гонки .

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

Не имея доступа к внутреннему дизайну Dragon Age: Inquisition , все, что может сделать каждый, - это размышлять о том, почему он ведет себя так, как он. Но я попробую, основываясь на некоторых вещах, которые я видел в своем собственном опыте:

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

Выполнение подобной программы на чем-то менее способном, чем среда, для которой она была настроена, вносит изменения синхронизации, которые являются результатом того, что код работает не так быстро или, что более вероятно, переключением контекста. Переключение контекста происходит физическим (т. Е. Физические ядра ЦП переключаются между работой, которую держат его логические ядра) и логическим (т. Е. ОС на ЦП распределяет работу по ядрам) способами, но это либо существенно отличается от того, что будет "ожидаемым" временем выполнения. Это может выявить плохое поведение.

Если Dragon Age: Inquisition не предпримет простого шага, чтобы убедиться в наличии достаточного количества физических ядер, прежде чем продолжить, это вина EA. Вероятно, они тратят небольшое состояние, отправляя звонки в службу поддержки и электронные письма от людей, которые пытались запустить игру на слишком маленьком оборудовании.

Blrfl
источник
1
Некоторые игроки говорят, что это вызвано тем, что DRM работает на 2 ядрах, а сама игра работает на 2 ядрах. Когда DRM и игровые потоки работают на одном и том же ядре, они портятся. Но это не звучит правильно для меня, это может быть небольшая история, составленная игроком, который мало знает об архитектуре SW или HW.
Уилмз
4
Условия гонки на самом деле не имеют ничего общего с количеством ядер, -1 ... одноядерный компьютер с несколькими виртуальными потоками может иметь условия гонки, полностью зависящие от техники среза времени выполнения, или многоядерная система может избежать зависимости от всех условий гонки. о том, как строго обстоят дела с мембранными операциями ...
Джимми Хоффа
1
@Reek: Без глубоких знаний о том, как работает программа, все что-то догадывается. Два ядра, чтобы сделать только DRM, кажутся мне немного чрезмерными.
Blrfl
1
@JimmyHoffa: я не согласен. Состояние гонки все еще является состоянием гонки, даже если оно не вызывает нежелательного поведения. Количество ядер может влиять на то, происходит ли это поведение, о чем спрашивал спрашивающий, но я не назвал его единственной переменной.
Blrfl
-1

Для этого в Windows есть встроенная функциональность: функция GetLogicalProcessorInformation находится в Windows API . Вы можете вызвать его из своей программы, чтобы получить информацию о ядрах, виртуальных ядрах и гиперпоточности.

Таким образом, ответ на ваш вопрос будет: да.

Питер Б
источник
3
Я не спрашиваю "Могу ли я узнать никаких ядер из кода?" ... Такой код будет злонамеренным (заставляет вас покупать более дорогой процессор для запуска программы - без необходимости в вычислительных ресурсах).
uylmz
3
Эта функция дает гораздо больше информации, чем просто «количество ядер». С помощью этой информации вы можете вычесть физические ядра, логические ядра и многое другое. Если вы можете вычесть это, то вы можете написать программное обеспечение для использования этой информации. В хорошем или плохом смысле (вылетает программа, когда вы видите 4 ядра, но менее 4 физических ядер).
Питер Б
1
Это может работать в Windows, но как насчет OSX / Linux / iOS / Android / и т. Д.? Хотя он ссылается на игру как на случай, когда такое поведение наблюдается (и естественной корреляцией будет Windows = Gaming), это, похоже, не специфичный для игры запрос.
Роберт
Для такой игры, как Dragon Age, речь идет о Windows / XBox / PS4.
Gort the Robot
В Linux есть /proc/cpuinfoи sysconf(_SC_NPROCESSORS_ONLN)(последнее упомянуто в POSIX). Однако использование информации для обеспечения минимального порога производительности все еще является довольно плохой формой.
Цао