Advertisement
fsb4000

C

Feb 12th, 2020
699
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.59 KB | None | 0 0
  1. // This is a personal academic project. Dear PVS-Studio, please check it.
  2. // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <stdbool.h>
  6. #include <string.h>
  7. #include <time.h>
  8. #include <assert.h>
  9. #include <limits.h>
  10. #include <inttypes.h>
  11.  
  12. #include <omp.h>
  13.  
  14. #ifndef __GNUC__
  15. #define __attribute__(...)
  16. #endif
  17.  
  18. #ifndef _MSC_VER
  19. #define _Ret_notnull_
  20. #define _Ret_valid_
  21.  
  22. #define _Out_
  23. #define _In_
  24. #define _In_z_
  25. #define _Inout_
  26.  
  27. #define _Out_writes_z_(size)
  28. #define _Out_writes_(size)
  29. #define _In_reads_(size)
  30. #define _Inout_updates_(size)
  31.  
  32. #define _Post_writable_byte_size_(size)
  33. #define _Post_readable_byte_size_(size)
  34.  
  35. #define _Post_writable_size_(size)
  36. #define _Post_readable_size_(size)
  37.  
  38. #define _Post_invalid_
  39. #define _Post_notnull_
  40. #define _Post_ptr_invalid_
  41.  
  42. #define _Ret_writes_(size)
  43. #define _Ret_writes_z_(size)
  44.  
  45. #endif
  46.  
  47. #ifndef __cplusplus
  48. #ifndef thread_local
  49. #define thread_local _Thread_local
  50. #endif
  51. #endif
  52.  
  53. typedef char* owned_string;
  54.  
  55. typedef char* unowned_string;
  56.  
  57. typedef  owned_string* owned_array_owned_string;
  58.  
  59. typedef unowned_string* unowned_array_unowned_string;
  60.  
  61. typedef unowned_string* unowned_string_ptr;
  62.  
  63. typedef void* not_null_void_ptr;
  64.  
  65. typedef char* not_null_char_ptr;
  66.  
  67. _Ret_notnull_
  68. __attribute__((returns_nonnull))
  69. not_null_void_ptr unwrap(_Post_notnull_ void* p)
  70. {
  71.     if (p == NULL) {
  72.         fprintf(stderr, "unwrap\n");
  73.         abort();
  74.     }
  75.     return p;
  76. }
  77.  
  78. _Post_writable_byte_size_(size)
  79. __attribute__((returns_nonnull))
  80. not_null_void_ptr my_malloc(size_t size)
  81. {
  82.     return unwrap(malloc(size));
  83. }
  84.  
  85. _Ret_writes_z_(buf_size)
  86. __attribute__((returns_nonnull)) __attribute__((nonnull))
  87. unowned_string random_str_from_buffer(size_t buf_size, _Out_writes_z_(buf_size) not_null_char_ptr  buffer)
  88. {
  89.     assert(buf_size != 0);
  90.  
  91.     static const char chars[] =
  92.         "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  93.     static const size_t chars_len = sizeof(chars) - 1; // не учитываем последний '\0'
  94.  
  95.     for (size_t i = 0; i < buf_size - 1; ++i) {
  96.         buffer[i] = chars[ (size_t)((rand() / (double)RAND_MAX) * (double)chars_len)];
  97.     }
  98.     buffer[buf_size - 1] = '\0';
  99.     return buffer;
  100. }
  101.  
  102. _Ret_writes_z_(len + 1)
  103. __attribute__((returns_nonnull))
  104. owned_string random_str(size_t len)
  105. {
  106.     owned_string random_chars = (owned_string)my_malloc(len + 1); // +1 для '\0'
  107.     (void)random_str_from_buffer(len + 1, random_chars);
  108.     return random_chars;
  109. }
  110.  
  111. _Ret_writes_z_(101)
  112. __attribute__((returns_nonnull))
  113. owned_string random_string_100(void)
  114. {
  115.     return random_str(100);
  116. }
  117.  
  118. _Ret_writes_(len)
  119. __attribute__((returns_nonnull))  __attribute__((nonnull))
  120. owned_array_owned_string array_init(size_t len, _In_ owned_string(*initializer) ())
  121. {
  122.     owned_array_owned_string array =
  123.         (owned_array_owned_string)my_malloc(len * sizeof(owned_string));
  124.  
  125.     for (size_t i = 0; i < len; ++i) {
  126.         array[i] = initializer();
  127.     }
  128.     return array;
  129. }
  130.  
  131. __attribute__((nonnull))
  132. void array_free(size_t len, _Post_ptr_invalid_ _In_reads_(len) owned_array_owned_string array)
  133. {
  134.     for (size_t i = 0; i < len; ++i) {
  135.         free(array[i]);
  136.     }
  137.     free(array);
  138. }
  139.  
  140. thread_local unowned_string_ptr test_string = NULL;
  141.  
  142. __attribute__((nonnull))
  143. bool has_substring_of_test_string_in_str(_In_z_ unowned_string str)
  144. {
  145.     assert(test_string != NULL);
  146.     return strstr(str, *test_string) != NULL;
  147. }
  148.  
  149. __attribute__((nonnull))
  150. bool array_exists(size_t len,
  151.     _In_reads_(len) unowned_array_unowned_string arr, _In_ bool (*pred)(unowned_string))
  152. {
  153.     for (size_t i = 0; i < len; ++i) {
  154.         if (pred(arr[i])) {
  155.             return true;
  156.         }
  157.     }
  158.     return false;
  159. }
  160.  
  161. thread_local size_t array_size_for_map = 0;
  162. thread_local unowned_array_unowned_string array_for_map = NULL;
  163.  
  164. void setup_op_map_closure(size_t len, unowned_array_unowned_string array)
  165. {
  166.     array_size_for_map = len;
  167.     array_for_map = array;
  168. }
  169.  
  170. int op_map(int _)
  171. {
  172.     assert(array_for_map != NULL);
  173.     assert(array_size_for_map != 0);
  174.  
  175.     (void)_;
  176.     char buffer[21];
  177.     unowned_string s20 = random_str_from_buffer(sizeof(buffer), buffer);
  178.     test_string = &s20;
  179.     bool found = array_exists(array_size_for_map, array_for_map,
  180.         has_substring_of_test_string_in_str);
  181.     test_string = NULL; // убираем висячий указатель
  182.     return found ? 1 : 0;
  183.    
  184. }
  185.  
  186. int op_reduce(int acc, int current)
  187. {
  188.     return acc + current;
  189. }
  190.  
  191. int seq_parallel_map_int_reduce_int(int start, int end, int(*map_op)(int), int acc, int(*bin_op)(int, int))
  192. {
  193.     #pragma omp parallel
  194.     {
  195.         int temp = acc;
  196.         #pragma omp for
  197.         for (int i = start; i < end; ++i)
  198.         {
  199.             temp = bin_op(temp, map_op(i));
  200.         }
  201.         #pragma omp critical
  202.         {
  203.             acc = bin_op(acc, temp);
  204.         }
  205.     }
  206.     return acc;
  207. }
  208.  
  209. int main(int argc, char** argv)
  210. {
  211.     (void)argc;
  212.     unsigned some_random = (unsigned)((uintmax_t)&argv % UINT_MAX);
  213.     #pragma omp parallel
  214.     {
  215.         srand(((unsigned)time(NULL)) + omp_get_thread_num()*8
  216.             + some_random
  217.         );
  218.     }
  219.  
  220.     for (int i = 0; i < 10; ++i)
  221.     {
  222.         double start = omp_get_wtime();
  223.         size_t array_size = 100000;
  224.         owned_array_owned_string array = array_init(array_size, random_string_100);
  225.  
  226.         #pragma omp parallel
  227.         {
  228.             setup_op_map_closure(array_size, array);
  229.         }
  230.         int matches = seq_parallel_map_int_reduce_int(
  231.             0, 1000,
  232.             op_map,
  233.             0, op_reduce
  234.         );
  235.  
  236.         array_free(array_size, array);
  237.         #pragma omp parallel
  238.         {
  239.             setup_op_map_closure(0, NULL); // Убираем висячий указатель на array
  240.         }
  241.  
  242.         double end = omp_get_wtime();
  243.         double time_elapsed = end - start;
  244.         printf("%d strings matches, time=%f\n", matches, time_elapsed);
  245.     }
  246. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement