Войти
ПрограммированиеФорумОбщее

Delphi: Точный таймер (Win API) (комментарии) (4 стр)

Страницы: 1 2 3 4 5 6 Следующая »
#45
1:30, 26 апр 2020

Delfigamer
> Так в том и суть, что дельты от разных - будут среди выбросов и потому
> отрежутся.
Кем отрежутся? Что ты будешь отрезать если у тебя, скажем, половина выборки фейковая? А если большая часть? А если вся? А зачем вообще этот геморрой, если можно этого избежать?

#46
1:49, 26 апр 2020

exchg
А типа когда посреди измерения ОС выталкивает твой поток и сажает в холодильник на пару лямов, это легит статистика?
Или у тебя на работе особая версия винды, которая перекидывает поток между ядрами каждые 100 тактов?
Я исхожу из предположения, что через rdtsc мы измеряем время работы нашего кода, а не системного шедулера. И что мы измеряем каждую операцию отдельно и собираем какую-никакую статистику, а не закручиваем цикл из 100500 итераций и ищем среднее по курятнику. Это объясняет мою позицию?

#47
7:26, 26 апр 2020

Cheb
> Windows ARM - интересный вопрос. Free Pascal поддерживает только Windows CE,
> преданье старины глубокой, а Windows 10 ARM
ты просто не следишь на новостями

Оффтоп:

+ кишочки скиффа от гд.ру
#48
10:05, 26 апр 2020

Delfigamer
> А типа когда посреди измерения ОС выталкивает твой поток и сажает в холодильник
> на пару лямов, это легит статистика?
И это тоже, смирись.

> Или у тебя на работе особая версия винды, которая перекидывает поток между
> ядрами каждые 100 тактов?
У меня как и у всех, SMP с пулом ядер из которого выбирается свободно ядро каждый слайс контекст свитча. А у тебя какая то версия где тебе гарантируют выполнение на одном ядре?

> Я исхожу из предположения, что через rdtsc мы измеряем время работы нашего
> кода, а не системного шедулера.
Это не верное предположение. Об этом говорит даже простой факт существования rdtscp. Ну и факт того, что такое измерение, даже будучи корректным, измеряет время твоего кода + кода ОС в том числе и шедулерра. Тем более я просто уверен что микрософт занесли прибивание треда к ядру внутрь QPC.

> И что мы измеряем каждую операцию отдельно и собираем какую-никакую статистику,
Как вы это делаете?

> Это объясняет мою позицию?
Да я ее понял сразу, я не понял как ты ее реализовывать собрался.

#49
18:11, 26 апр 2020

>Проще же просто выкидывать выбросы в дельтах.

>когда посреди измерения ОС выталкивает твой поток и сажает в холодильник

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

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

#50
18:24, 26 апр 2020

Чем вас timeGetTime не устраивает?

#51
19:12, 26 апр 2020

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

#52
19:30, 26 апр 2020

exchg
> Это не верное предположение.
Ты всё-таки не понял. "Мы измеряем собственное время" означает умысел, а не как-нибудь сложившийся результат. Мы не смотрим на экран и внезапно видим, что шедулера нет, а наоборот, специально проверяем сэмплы и отбрасываем те, посреди которых произошло переключение контекста, как шумовые выбросы.

exchg
> А у тебя какая то версия где тебе гарантируют выполнение на одном ядре?
У моей версии слайс измеряется в миллионах тактов, так что основная масса сэмплов оказывается целиком внутри слайса, и переключения видны как выбросы в выборке.

exchg
> Как вы это делаете?
Зависит от проблемы икс.
У себя в рейтрейсере я просто вывожу число на экран на манер fps.
Если нужно, чтобы статистика прямо собиралась - в идеале ведётся таблица частот, но если идеал не нужен, то можно обойтись классическим мин/макс/авг/стдев.

#53
19:33, 26 апр 2020

exchg
> В данном случае с чистым rdsc ты можешь попасть в ситуацию, когда у тебя просто
> случайный набор дельт и весь твой поток это мусор.
Только если размер слайса сравним с размером сэмпла.

#54
20:04, 26 апр 2020

Delfigamer
> а наоборот, специально проверяем сэмплы и отбрасываем те, посреди которых
> произошло переключение контекста, как шумовые выбросы.
Все я понял, поэтому спросил как вы находите выбросы в дельтах которые посчитаны между несвязанными/не синхронизированными часами между собой "часами"?

> У моей версии слайс измеряется в миллионах тактов, так что основная масса
> сэмплов оказывается целиком внутри слайса, и переключения видны как выбросы в
> выборке.
Это было бы справедлив только в случае, если начало таймера попадает в начало слайса. А так как это больше случайное совпадение то исходные не верны.

> > В данном случае с чистым rdsc ты можешь попасть в ситуацию, когда у тебя
> > просто
> > случайный набор дельт и весь твой поток это мусор.
> Только если размер слайса сравним с размером сэмпла.
Более правдоподобно - "только если размер слайса больше или равен", но опять же это справедливо если тебе кто-то гарантирует, что таймер старт будет вначале слайса. А так как сэмпл начинается в произвольном месте слайса, то это не выглядит верным утверждением.

#55
21:48, 26 апр 2020

exchg
> Более правдоподобно - "только если размер слайса больше или равен"
Нет, именно "сравним".
Если я замеряю стоимость пересечения луча со сценой, и на эту операцию уходит порядка 5000 тактов - то вероятность пересечь границу слайса составляет около 0.001.

> Это было бы справедлив только в случае, если начало таймера попадает в начало
> слайса.
Это не причём. ОС совершенно без разницы, чем занимается твоя программа, если только твоя программа сама не пойдёт к ОС. Следовательно, при отсутствии системных вызовов и пэйдж-фолтов, переключения контекста распределены равномерно по всему протяжению кода. А значит - и смещение таймера внутри слайса так же окажется распределено равномерно. Отсюда, доля запоротых сэмплов - это просто отношение длины сэмпла к длине слайса. В моём случае - «мы измеряем каждую операцию отдельно и собираем какую-никакую статистику, а не закручиваем цикл из 100500 итераций и ищем среднее по курятнику» - это малое число. Следовательно,
> выбросы в дельтах которые посчитаны между несвязанными/не синхронизированными
> часами между собой "часами"
- это неверное утверждение, поскольку подавляющее большинство сэмплов будет всё-таки посчитано без переключения часов.

#56
22:50, 26 апр 2020

Delfigamer

Уточню терминологию, на всякий случай.
Слайс - время работы треда меду контекст свитчами.
Сэмпл - некий набор команд ограниченный вызовами timer.start, timer.stop.
timer - rdtsc

> Если я замеряю стоимость пересечения луча со сценой, и на эту операцию уходит
> порядка 5000 тактов - то вероятность пересечь границу слайса составляет около
> 0.001.
А если семпл начался за 1 такт до конца слайса то все семплы пересекут границу слайса с вероятностью 1. Только ты никак не узнаешь когда именно начался сэмпл )))

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

> А значит - и смещение таймера внутри слайса так же окажется распределено
> равномерно.
Да, например равномерно за 1 такт до конца слайса. А в ообщем случае в случайном месте.

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

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

#57
2:15, 27 апр 2020

>А если семпл начался за 1 такт до конца слайса то все семплы пересекут границу слайса с вероятностью 1.
Нет, если использовать, как я, релятивистский таймер, основанный на запоминании предыдущего значения TSC и сравнивания с текущим.
Он не даёт "время, прошедшее с t0", он даёт "время, прошедшее с предыдущего вызова", что актуально при профайлинге.

З.Ы. Нашёл статью, где *очень* подробно всё расписано, по версиям виндовс и степеням древности проца. https://docs.microsoft.com/en-us/windows/win32/sysinfo/acquiring-… n-time-stamps
QPC использует TSC на процах, поддерживающих invariant TSC и откатывается на более кондовые механизмы, где её нет.
Можно довериться ей, или можно сделать всё самому и поиметь небольшой профит во времени вызова. Про поддержку invariant TSC можно спросить у CPUID.

#58
4:17, 27 апр 2020

exchg
> А если семпл начался за 1 такт до конца слайса то все семплы пересекут границу
> слайса с вероятностью 1.
Что? Нет же.

void Measure::Start()
{
    this->time = (uint64_t)_rdtsc();
}

void Measure::Stop()
{
    uint64_t delta = (uint64_t)_rdtsc - this->time;
    this->RecordSample(delta);
}

bool MeasuredTrace(TraceRequest& tr)
{
    static Measure m;
    m.Start();
    bool r = Trace(tr);
    m.Stop();
    return r;
}

void RenderStep()
{
    for (auto pixel: pixels) {
        Photon p = EmitPhoton(pixel);
        while (MeasuredTrace(p->tr)) {
            GatherPhoton(pixel, p);
            if (!ScatterPhoton(p)) {
                break;
            }
        }
    }
}

Если один сэмпл пересечёт границу - то только этот сэмпл и пересечёт, с чего это вдруг остальные должны как-то от этого поменяться?

#59
4:37, 27 апр 2020

exchg
> Тем более я просто уверен что микрософт занесли прибивание треда к ядру внутрь
> QPC.
Это как? Вот допустим происходит вызов QPC, винда сохраняет все регистры в текущем треде, ждет когда освободится нужный тред и читает там таймер? Звучит крайне не очень на мой взгляд. Я бы предположил, что винда вначале вычитывает такты со всех тредов, и знает дельту относительно друг друга. Кроме того для случаев, когда частота меняется - винда использует счетчик деленный на множитель. В этом кстати можно легко убедиться если посмотреть что возвращает QPF. Он вернет не реальные 3Ггц, а значение раз в 20 меньше этого.

Страницы: 1 2 3 4 5 6 Следующая »
ПрограммированиеФорумОбщее

Тема в архиве.