1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
|
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#include <aws/cal/cal.h>
#include <aws/cal/hash.h>
#include <aws/common/clock.h>
#include <aws/common/device_random.h>
#include <inttypes.h>
static void s_profile_streaming_hash_at_chunk_size(
struct aws_allocator *allocator,
struct aws_byte_cursor to_hash,
size_t chunk_size,
size_t alignment) {
struct aws_hash *hash_impl = aws_sha256_new(allocator);
AWS_FATAL_ASSERT(hash_impl);
struct aws_byte_buf output_buf;
AWS_FATAL_ASSERT(
!aws_byte_buf_init(&output_buf, allocator, AWS_SHA256_LEN) && "allocation of output buffer failed!");
struct aws_byte_cursor to_hash_seeked = to_hash;
uint64_t start = 0;
AWS_FATAL_ASSERT(!aws_high_res_clock_get_ticks(&start) && "clock get ticks failed.");
if (alignment) {
size_t alignment_miss = (uintptr_t)to_hash_seeked.ptr % alignment;
struct aws_byte_cursor unaligned_chunk = aws_byte_cursor_advance(&to_hash_seeked, alignment_miss);
AWS_FATAL_ASSERT(!aws_hash_update(hash_impl, &unaligned_chunk) && "hash compute of unaligned chunk failed");
}
while (to_hash_seeked.len) {
size_t remaining = chunk_size > to_hash_seeked.len ? to_hash_seeked.len : chunk_size;
struct aws_byte_cursor chunk_to_process = aws_byte_cursor_advance(&to_hash_seeked, remaining);
AWS_FATAL_ASSERT(!aws_hash_update(hash_impl, &chunk_to_process) && "hash compute of chunk failed");
}
AWS_FATAL_ASSERT(!aws_hash_finalize(hash_impl, &output_buf, 0) && "hash finalize failed");
uint64_t end = 0;
AWS_FATAL_ASSERT(!aws_high_res_clock_get_ticks(&end) && "clock get ticks failed");
fprintf(stdout, "SHA256 streaming computation took %" PRIu64 "ns\n", end - start);
aws_byte_buf_clean_up(&output_buf);
aws_hash_destroy(hash_impl);
}
static void s_profile_oneshot_hash(struct aws_allocator *allocator, struct aws_byte_cursor to_hash) {
struct aws_byte_buf output_buf;
AWS_FATAL_ASSERT(
!aws_byte_buf_init(&output_buf, allocator, AWS_SHA256_LEN) && "allocation of output buffer failed!");
uint64_t start = 0;
AWS_FATAL_ASSERT(!aws_high_res_clock_get_ticks(&start) && "clock get ticks failed.");
AWS_FATAL_ASSERT(!aws_sha256_compute(allocator, &to_hash, &output_buf, 0) && "Hash computation failed");
uint64_t end = 0;
AWS_FATAL_ASSERT(!aws_high_res_clock_get_ticks(&end) && "clock get ticks failed");
fprintf(stdout, "SHA256 oneshot computation took %" PRIu64 "ns\n", end - start);
aws_byte_buf_clean_up(&output_buf);
}
static void s_run_profiles(struct aws_allocator *allocator, size_t to_hash_size, const char *profile_name) {
fprintf(stdout, "********************* SHA256 Profile %s ************************************\n\n", profile_name);
struct aws_byte_buf to_hash;
AWS_FATAL_ASSERT(!aws_byte_buf_init(&to_hash, allocator, to_hash_size) && "failed to allocate buffer for hashing");
AWS_FATAL_ASSERT(!aws_device_random_buffer(&to_hash) && "reading random data failed");
struct aws_byte_cursor to_hash_cur = aws_byte_cursor_from_buf(&to_hash);
fprintf(stdout, "********************* Chunked/Alignment Runs *********************************\n\n");
fprintf(stdout, "****** 128 byte chunks ******\n\n");
fprintf(stdout, "8-byte alignment:\n");
s_profile_streaming_hash_at_chunk_size(allocator, to_hash_cur, 128, 8);
fprintf(stdout, "16-byte alignment:\n");
s_profile_streaming_hash_at_chunk_size(allocator, to_hash_cur, 128, 16);
fprintf(stdout, "64-byte alignment:\n");
s_profile_streaming_hash_at_chunk_size(allocator, to_hash_cur, 128, 64);
fprintf(stdout, "128-byte alignment:\n");
s_profile_streaming_hash_at_chunk_size(allocator, to_hash_cur, 128, 128);
fprintf(stdout, "\n****** 256 byte chunks ******\n\n");
fprintf(stdout, "8-byte alignment:\n");
s_profile_streaming_hash_at_chunk_size(allocator, to_hash_cur, 256, 8);
fprintf(stdout, "16-byte alignment:\n");
s_profile_streaming_hash_at_chunk_size(allocator, to_hash_cur, 256, 16);
fprintf(stdout, "64-byte alignment:\n");
s_profile_streaming_hash_at_chunk_size(allocator, to_hash_cur, 256, 64);
fprintf(stdout, "128-byte alignment:\n");
s_profile_streaming_hash_at_chunk_size(allocator, to_hash_cur, 256, 128);
fprintf(stdout, "\n******* 512 byte chunks *****\n\n");
fprintf(stdout, "8-byte alignment:\n");
s_profile_streaming_hash_at_chunk_size(allocator, to_hash_cur, 512, 8);
fprintf(stdout, "16-byte alignment:\n");
s_profile_streaming_hash_at_chunk_size(allocator, to_hash_cur, 512, 16);
fprintf(stdout, "64-byte alignment:\n");
s_profile_streaming_hash_at_chunk_size(allocator, to_hash_cur, 512, 64);
fprintf(stdout, "128-byte alignment:\n");
s_profile_streaming_hash_at_chunk_size(allocator, to_hash_cur, 512, 128);
fprintf(stdout, "\n********************** Oneshot Run *******************************************\n\n");
s_profile_oneshot_hash(allocator, to_hash_cur);
fprintf(stdout, "\n\n");
aws_byte_buf_clean_up(&to_hash);
}
int main(void) {
struct aws_allocator *allocator = aws_default_allocator();
aws_cal_library_init(allocator);
struct aws_hash *hash_impl = aws_sha256_new(allocator);
fprintf(stdout, "Starting profile run for Sha256 using implementation %s\n\n", hash_impl->vtable->provider);
s_run_profiles(allocator, 1024, "1 KB");
s_run_profiles(allocator, 1024 * 64, "64 KB");
s_run_profiles(allocator, 1024 * 128, "128 KB");
s_run_profiles(allocator, 1024 * 512, "512 KB");
aws_hash_destroy(hash_impl);
aws_cal_library_clean_up();
return 0;
}
|