/* midmul-profile.c: routines for profiling middle products Copyright (C) 2007, 2008, David Harvey This file is part of the zn_poly library (version 0.8). This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) version 3 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include "support.h" #include "profiler.h" #include "zn_poly_internal.h" /* Wrapper functions to make zn_array_midmul_fallback and zn_array_midmul_fft look as if they have the same signature as zn_array_midmul. */ void zn_array_midmul_fallback_wrapper( ulong* res, const ulong* op1, size_t len1, const ulong* op2, size_t len2, const zn_mod_t mod) { zn_array_midmul_fallback(res, op1, len1, op2, len2, 0, mod); } void zn_array_midmul_fft_wrapper( ulong* res, const ulong* op1, size_t len1, const ulong* op2, size_t len2, const zn_mod_t mod) { // call the FFT code with the correct scaling factor ulong scale = zn_array_midmul_fft_get_fudge(len1, len2, mod); zn_array_midmul_fft(res, op1, len1, op2, len2, scale, mod); } double profile_midmul(void* arg, unsigned long count) { profile_midmul_info_struct* info = (profile_midmul_info_struct*) arg; zn_mod_t mod; zn_mod_init(mod, info->n); ulong* buf1 = (ulong*) malloc(sizeof(ulong) * 2 * info->len); ulong* buf2 = (ulong*) malloc(sizeof(ulong) * info->len); ulong* buf3 = (ulong*) malloc(sizeof(ulong) * (info->len + 1)); // generate random inputs size_t i; for (i = 0; i < 2 * info->len; i++) buf1[i] = random_ulong(info->n); for (i = 0; i < info->len; i++) buf2[i] = random_ulong(info->n); void (*target)(ulong*, const ulong*, size_t, const ulong*, size_t, const zn_mod_t); switch (info->algo) { case ALGO_MIDMUL_BEST: target = zn_array_midmul; break; case ALGO_MIDMUL_FALLBACK: target = zn_array_midmul_fallback_wrapper; break; /* case ALGO_MIDMUL_KS1: target = zn_array_midmul_KS1; break; case ALGO_MIDMUL_KS2: target = zn_array_midmul_KS2; break; case ALGO_MIDMUL_KS3: target = zn_array_midmul_KS3; break; case ALGO_MIDMUL_KS4: target = zn_array_midmul_KS4; break; */ case ALGO_MIDMUL_FFT: target = zn_array_midmul_fft_wrapper; break; default: abort(); } // warm up ulong j; for (j = 0; j < count; j++) target(buf3, buf1, 2 * info->len, buf2, info->len, mod); // do the actual profile cycle_count_t t0 = get_cycle_counter(); for (j = 0; j < count; j++) target(buf3, buf1, 2 * info->len, buf2, info->len, mod); cycle_count_t t1 = get_cycle_counter(); free(buf3); free(buf2); free(buf1); zn_mod_clear(mod); return cycle_diff(t0, t1); } // end of file ****************************************************************