Гарантируется ли, что 2 последовательных std :: chrono :: stable_clock :: now () не будут равны? - PullRequest
4 голосов
/ 16 января 2020

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

Псевдокод:

StampedResult fn() {
  auto result = Calculations();
  auto time_stamp = std::chrono::steady_clock::now();
  return {time_stamp, result);
}

Теперь, если Calculations() всегда было сложным, это было бы автоматически решено. Но иногда Calculations() может немедленно вернуться.

Итак, я подумал, что мне следует проверить, могут ли 2 последовательных вызова steady_clock::now() вернуть одно и то же значение, например:

https://onlinegdb.com/BkiDAZRe8

На onlinegdb.com и на моем ноутбуке Intel® Core™ i7-8750H CPU @ 2.20GHz Я никогда не получу одно и то же возвращаемое значение. Но может ли какой-нибудь другой сверхвысокочастотный процессор на самом деле вернуть те же значения, учитывая наносекундную точность steady_clock?

Ответы [ 3 ]

6 голосов
/ 16 января 2020

Гарантируется ли, что 2 последовательных std :: chrono :: stable_clock :: now () не будут равны?

Стандарт не гарантируется. Цитата из последнего черновика:

[time.clock.steady]

Объекты класса stable_clock представляют часы, для которых значения time_point никогда не уменьшаются по мере продвижения физического времени и для каких значений time_point продвигаться с постоянной скоростью относительно реального времени. Таким образом, часы не могут быть отрегулированы.

Сохранение того же самого удовлетворяет требованию "никогда не уменьшать".

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


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

5 голосов
/ 16 января 2020

steady_clock требуется, чтобы не go назад, и это необходимо для продвижения вперед через регулярные промежутки времени. Вот и все. Даже не требуется иметь наносекундную точность (или для того, чтобы фактическая точность часов соответствовала точности их временных точек).

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

2 голосов
/ 16 января 2020

Нет. Нет гарантии, что два вызова не вернут одно и то же значение.

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

Короче говоря; Вы не можете использовать метку времени в качестве уникального идентификатора. Вы вероятно могли бы использовать "timestamp + thread_id", если идентификаторы потоков не используются повторно. Может быть, лучше сначала отсортировать по временной метке, а затем по монотонному c увеличивающемуся идентификатору, назначенному каждому потоку при его создании. Это гарантировало бы уникальность и установило бы sh фиксированный порядок сортировки.

...