LINUX.ORG.RU

clock() в Linux.

 


2

3

Собираю проект в линуксе, который разрабатывал в виндоусе. И там всё было хорошо с функцией clock().

А в линуксе наблюдаются странности с функцией clock() уже не в первый раз такое наблюдаю.

Это относится к участку кода типа

unsigned start = clock();
//...
unsigned clk = clock() - start;

Результат получается многократно больше чем нужно. Кому-нибудь знакома такая проблема?



Последнее исправление: user08 (всего исправлений: 2)

The value returned is the CPU time used so far as a clock_t; to get the number of seconds used, divide by CLOCKS_PER_SEC. If the processor time used is not available or its value cannot be represented, the function returns the value (clock_t) -1.

Deleted
()
Ответ на: комментарий от Deleted

The value returned is the CPU time used so far as a clock_t; to get the number of seconds used, divide by CLOCKS_PER_SEC. If the processor time used is not available or its value cannot be represented, the function returns the value (clock_t) -1.

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

user08
() автор топика

В венде и линуксе clock() имеет разный смысл.

The clock function tells how much wall-clock time has passed since the CRT initialization during process start. Note that this function does not strictly conform to ISO C, which specifies net CPU time as the return value. To obtain CPU times, use the Win32 GetProcessTimes function. To determine the elapsed time in seconds, divide the value returned by the clock function by the macro CLOCKS_PER_SEC.

Deleted
()

Используй clock_gettime

anonymous
()
Ответ на: комментарий от xaizek

divide by CLOCKS_PER_SEC

Это есть. Ещё раз обращаю внимание что в виндоусе результаты получаются правильные, а в линуксе с тем же кодом многократно больше.

user08
() автор топика

Приведите небольшой пример кода, который легко скомпилировать и который демонстрирует проблему.

Приведите точные значения, которые он выдаёт у Вас на обеих ОС.

У меня

#include <time.h>
#include <stdio.h>

int main(int argc, char** argv) {
	clock_t start, end;
	volatile unsigned int i;

	start = clock();

	for (i = 0; i < 1000000000; i++);

	end = clock();

	printf("%g\n", ((double)(end-start))/CLOCKS_PER_SEC);
	return 0;
}
$ time ./a.out 
4.16239

real    0m4,168s
user    0m4,164s
sys     0m0,004s
$ time wine a.exe 
4.159

real    0m5,254s
user    0m4,160s
sys     0m0,020s

не воспроизводится (лишняя секунда уходит на I/O во время запуска самого Wine).

anonymous
()

Не знаю конкретно в чем проблема, но в Linux (по крайней мере в glibc): тип clock_t является typedef к long. А тут unsigned...

P.S. в MSVC тоже long, значит проблема не в этом, раз на Windows работает, а под Linux нет.

Удваиваю привести пример, как попросил аноним...

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 2)

В clock возвращает суммарное CPU-время потраченное всеми потоками текущего процессора.

Почти минимальный пример:

#include <math.h>
#include <time.h>

#include <algorithm>
#include <chrono>
#include <iostream>
#include <random>
#include <vector>

std::vector<double> get_random_vector(size_t size)
{
  std::vector<double> result(size);

#pragma omp parallel shared(result)
  {
    std::random_device rd;
    std::mt19937_64 gen(rd());
    std::normal_distribution<double> dis(6.0, 2.0);

#pragma omp for schedule(static)
    for (size_t i = 0; i < size; i++) {
      result[i] = dis(gen);
    }
  }

  return result;
}

int main()
{
  auto sc_start = std::chrono::steady_clock::now();
  auto c_start = clock();

  auto xs = get_random_vector(1000000);
  (void)xs;

  auto sc_end = std::chrono::steady_clock::now();
  auto c_end = clock();

  std::chrono::duration<double> sc_wt = sc_end - sc_start;
  double c_wt = ((double)(c_end - c_start)) / CLOCKS_PER_SEC;

  std::cout << "Steady clock: " << sc_wt.count() << "\n";
  std::cout << "clock: " << c_wt << "\n";

  return 0;
}

AlexVR ★★★★★
()
Ответ на: комментарий от AlexVR

В clock возвращает суммарное CPU-время потраченное всеми потоками текущего процессора.

Скорее всего ты прав, что проблема именно в этом.

В Linux

./a.out
Steady clock: 0.073498
clock: 0.203125
В Windows
Steady clock: 0.0449874
clock: 0.045
Не знал, что в Windows clock возвращает только для главного потока, полезной оказалась тема...

fsb4000 ★★★★★
()
Ответ на: комментарий от user08

Ещё раз обращаю внимание что в виндоусе результаты получаются правильные

Нет. Читай выше цитату из MSDN. clock() должна делать не то, что она делает в венде. В венде она просто считает время с начала инициализации рантайма.

Deleted
()
Ответ на: комментарий от fsb4000

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

user08
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.