Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // This is a personal academic project. Dear PVS-Studio, please check it.
- // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
- #include <stdlib.h>
- #include <stdio.h>
- #include <stdbool.h>
- #include <string.h>
- #include <time.h>
- #include <assert.h>
- #include <limits.h>
- #include <inttypes.h>
- #include <omp.h>
- #ifndef __GNUC__
- #define __attribute__(...)
- #endif
- #ifndef _MSC_VER
- #define _Ret_notnull_
- #define _Ret_valid_
- #define _Out_
- #define _In_
- #define _In_z_
- #define _Inout_
- #define _Out_writes_z_(size)
- #define _Out_writes_(size)
- #define _In_reads_(size)
- #define _Inout_updates_(size)
- #define _Post_writable_byte_size_(size)
- #define _Post_readable_byte_size_(size)
- #define _Post_writable_size_(size)
- #define _Post_readable_size_(size)
- #define _Post_invalid_
- #define _Post_notnull_
- #define _Post_ptr_invalid_
- #define _Ret_writes_(size)
- #define _Ret_writes_z_(size)
- #endif
- #ifndef __cplusplus
- #ifndef thread_local
- #define thread_local _Thread_local
- #endif
- #endif
- typedef char* owned_string;
- typedef char* unowned_string;
- typedef owned_string* owned_array_owned_string;
- typedef unowned_string* unowned_array_unowned_string;
- typedef unowned_string* unowned_string_ptr;
- typedef void* not_null_void_ptr;
- typedef char* not_null_char_ptr;
- _Ret_notnull_
- __attribute__((returns_nonnull))
- not_null_void_ptr unwrap(_Post_notnull_ void* p)
- {
- if (p == NULL) {
- fprintf(stderr, "unwrap\n");
- abort();
- }
- return p;
- }
- _Post_writable_byte_size_(size)
- __attribute__((returns_nonnull))
- not_null_void_ptr my_malloc(size_t size)
- {
- return unwrap(malloc(size));
- }
- _Ret_writes_z_(buf_size)
- __attribute__((returns_nonnull)) __attribute__((nonnull))
- unowned_string random_str_from_buffer(size_t buf_size, _Out_writes_z_(buf_size) not_null_char_ptr buffer)
- {
- assert(buf_size != 0);
- static const char chars[] =
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- static const size_t chars_len = sizeof(chars) - 1; // не учитываем последний '\0'
- for (size_t i = 0; i < buf_size - 1; ++i) {
- buffer[i] = chars[ (size_t)((rand() / (double)RAND_MAX) * (double)chars_len)];
- }
- buffer[buf_size - 1] = '\0';
- return buffer;
- }
- _Ret_writes_z_(len + 1)
- __attribute__((returns_nonnull))
- owned_string random_str(size_t len)
- {
- owned_string random_chars = (owned_string)my_malloc(len + 1); // +1 для '\0'
- (void)random_str_from_buffer(len + 1, random_chars);
- return random_chars;
- }
- _Ret_writes_z_(101)
- __attribute__((returns_nonnull))
- owned_string random_string_100(void)
- {
- return random_str(100);
- }
- _Ret_writes_(len)
- __attribute__((returns_nonnull)) __attribute__((nonnull))
- owned_array_owned_string array_init(size_t len, _In_ owned_string(*initializer) ())
- {
- owned_array_owned_string array =
- (owned_array_owned_string)my_malloc(len * sizeof(owned_string));
- for (size_t i = 0; i < len; ++i) {
- array[i] = initializer();
- }
- return array;
- }
- __attribute__((nonnull))
- void array_free(size_t len, _Post_ptr_invalid_ _In_reads_(len) owned_array_owned_string array)
- {
- for (size_t i = 0; i < len; ++i) {
- free(array[i]);
- }
- free(array);
- }
- thread_local unowned_string_ptr test_string = NULL;
- __attribute__((nonnull))
- bool has_substring_of_test_string_in_str(_In_z_ unowned_string str)
- {
- assert(test_string != NULL);
- return strstr(str, *test_string) != NULL;
- }
- __attribute__((nonnull))
- bool array_exists(size_t len,
- _In_reads_(len) unowned_array_unowned_string arr, _In_ bool (*pred)(unowned_string))
- {
- for (size_t i = 0; i < len; ++i) {
- if (pred(arr[i])) {
- return true;
- }
- }
- return false;
- }
- thread_local size_t array_size_for_map = 0;
- thread_local unowned_array_unowned_string array_for_map = NULL;
- void setup_op_map_closure(size_t len, unowned_array_unowned_string array)
- {
- array_size_for_map = len;
- array_for_map = array;
- }
- int op_map(int _)
- {
- assert(array_for_map != NULL);
- assert(array_size_for_map != 0);
- (void)_;
- char buffer[21];
- unowned_string s20 = random_str_from_buffer(sizeof(buffer), buffer);
- test_string = &s20;
- bool found = array_exists(array_size_for_map, array_for_map,
- has_substring_of_test_string_in_str);
- test_string = NULL; // убираем висячий указатель
- return found ? 1 : 0;
- }
- int op_reduce(int acc, int current)
- {
- return acc + current;
- }
- int seq_parallel_map_int_reduce_int(int start, int end, int(*map_op)(int), int acc, int(*bin_op)(int, int))
- {
- #pragma omp parallel
- {
- int temp = acc;
- #pragma omp for
- for (int i = start; i < end; ++i)
- {
- temp = bin_op(temp, map_op(i));
- }
- #pragma omp critical
- {
- acc = bin_op(acc, temp);
- }
- }
- return acc;
- }
- int main(int argc, char** argv)
- {
- (void)argc;
- unsigned some_random = (unsigned)((uintmax_t)&argv % UINT_MAX);
- #pragma omp parallel
- {
- srand(((unsigned)time(NULL)) + omp_get_thread_num()*8
- + some_random
- );
- }
- for (int i = 0; i < 10; ++i)
- {
- double start = omp_get_wtime();
- size_t array_size = 100000;
- owned_array_owned_string array = array_init(array_size, random_string_100);
- #pragma omp parallel
- {
- setup_op_map_closure(array_size, array);
- }
- int matches = seq_parallel_map_int_reduce_int(
- 0, 1000,
- op_map,
- 0, op_reduce
- );
- array_free(array_size, array);
- #pragma omp parallel
- {
- setup_op_map_closure(0, NULL); // Убираем висячий указатель на array
- }
- double end = omp_get_wtime();
- double time_elapsed = end - start;
- printf("%d strings matches, time=%f\n", matches, time_elapsed);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement