bench-random-lock.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /* Benchmark internal libc locking functions used in random.
  2. Copyright (C) 2022-2026 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <https://www.gnu.org/licenses/>. */
  15. #define TEST_MAIN
  16. #define TEST_NAME "random-lock"
  17. #define TEST_FUNCTION test_main
  18. #include <pthread.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include "bench-timing.h"
  22. #include "json-lib.h"
  23. /* Modern cores run 20M iterations in about 1 second. */
  24. #define NUM_ITERS 50000000
  25. /* Measure the overhead of __libc_lock_lock and __libc_lock_unlock by
  26. calling random (). */
  27. static void
  28. bench_random_lock (json_ctx_t *json_ctx, size_t iters)
  29. {
  30. timing_t start, stop, total;
  31. srandom (0);
  32. /* Warmup to reduce variations due to frequency scaling. */
  33. for (int i = 0; i < iters / 4; i++)
  34. (void) random ();
  35. TIMING_NOW (start);
  36. for (int i = 0; i < iters; i++)
  37. (void) random ();
  38. TIMING_NOW (stop);
  39. TIMING_DIFF (total, start, stop);
  40. json_element_double (json_ctx, (double) total / (double) iters);
  41. }
  42. static void *
  43. thread_start (void *p)
  44. {
  45. return p;
  46. }
  47. int
  48. test_main (void)
  49. {
  50. json_ctx_t json_ctx;
  51. json_init (&json_ctx, 0, stdout);
  52. json_document_begin (&json_ctx);
  53. json_attr_string (&json_ctx, "timing_type", TIMING_TYPE);
  54. json_attr_object_begin (&json_ctx, "functions");
  55. json_attr_object_begin (&json_ctx, "random");
  56. json_attr_string (&json_ctx, "bench-variant", "single-threaded");
  57. json_array_begin (&json_ctx, "results");
  58. /* Run benchmark single threaded. */
  59. bench_random_lock (&json_ctx, NUM_ITERS);
  60. json_array_end (&json_ctx);
  61. json_attr_object_end (&json_ctx);
  62. json_attr_object_begin (&json_ctx, "random");
  63. json_attr_string (&json_ctx, "bench-variant", "multi-threaded");
  64. json_array_begin (&json_ctx, "results");
  65. /* Start a short thread to force SINGLE_THREAD_P == false. This relies on
  66. the runtime disabling single-threaded optimizations when multiple
  67. threads are used, even after they finish. */
  68. pthread_t t;
  69. pthread_create (&t, NULL, thread_start, NULL);
  70. pthread_join (t, NULL);
  71. /* Repeat benchmark with single-threaded optimizations disabled. */
  72. bench_random_lock (&json_ctx, NUM_ITERS);
  73. json_array_end (&json_ctx);
  74. json_attr_object_end (&json_ctx);
  75. json_attr_object_end (&json_ctx);
  76. json_document_end (&json_ctx);
  77. return 0;
  78. }
  79. #include "support/test-driver.c"