[FFmpeg-devel] [PATCH 10/10] tools/crypto_bench: add support for multiple lavu versions by cpuflag

Rodger Combs rodger.combs at gmail.com
Mon Oct 19 11:29:49 CEST 2015


> On Oct 14, 2015, at 09:15, Nicolas George <george at nsup.org> wrote:
> 
> Le primidi 21 vendémiaire, an CCXXIV, Rodger Combs a écrit :
>> ---
>> tools/crypto_bench.c | 51 +++++++++++++++++++++++++++++++++++++++++++--------
>> 1 file changed, 43 insertions(+), 8 deletions(-)
>> 
>> diff --git a/tools/crypto_bench.c b/tools/crypto_bench.c
>> index 0b1bfc8..f84e2a7 100644
>> --- a/tools/crypto_bench.c
>> +++ b/tools/crypto_bench.c
>> @@ -32,6 +32,7 @@
>> #include "libavutil/crc.h"
>> #include "libavutil/intreadwrite.h"
>> #include "libavutil/timer.h"
>> +#include "libavutil/cpu.h"
>> 
>> #ifndef AV_READ_TIME
>> #define AV_READ_TIME(x) 0
>> @@ -65,6 +66,7 @@ struct hash_impl {
>>     const char *name;
>>     void (*run)(uint8_t *output, const uint8_t *input, unsigned size);
>>     const char *output;
>> +    int cpu_versions;
>> };
>> 
>> /***************************************************************************
>> @@ -658,6 +660,16 @@ static unsigned crc32(const uint8_t *data, unsigned size)
>>     return av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0, data, size);
>> }
>> 
>> +static const struct {
>> +    int flag;
>> +    const char *name;
>> +} cpu_flag_tab[] = {
>> +#if ARCH_X86
>> +    { AV_CPU_FLAG_AESNI,     "aesni"      },
>> +#endif
>> +    { 0 }
>> +};
>> +
>> static void run_implementation(const uint8_t *input, uint8_t *output,
>>                                struct hash_impl *impl, unsigned size)
>> {
>> @@ -671,6 +683,29 @@ static void run_implementation(const uint8_t *input, uint8_t *output,
>>     if (enabled_libs  && !av_stristr(enabled_libs,  impl->lib) ||
>>         enabled_algos && !av_stristr(enabled_algos, impl->name))
>>         return;
>> +
> 
>> +    if (impl->cpu_versions && !strcmp(impl->lib, "lavu")) {
> 
> Could you play with the macros in order to have cpu_versions only in the
> libraries that support it?
> 
Probably possible, but unless we want to provide a way to set cpuflags for other libraries (do the they even provide a facility for that?), the simple name check works well enough.

>> +        char lib_name[32];
>> +        struct hash_impl impl2 = *impl;
>> +        int real_flags = av_get_cpu_flags();
>> +        int current_flags = real_flags;
>> +        impl2.cpu_versions = 0;
>> +        impl2.lib = lib_name;
>> +        for (i = 0; cpu_flag_tab[i].flag; i++) {
>> +            if (cpu_flag_tab[i].flag & impl->cpu_versions &&
>> +                real_flags & cpu_flag_tab[i].flag) {
>> +                snprintf(lib_name, sizeof(lib_name), "lavu_%s", cpu_flag_tab[i].name);
> 
>> +                run_implementation(input, output, &impl2, size);
>> +                current_flags &= ~cpu_flag_tab[i].flag;
>> +                av_force_cpu_flags(current_flags);
> 
> It looks a bit strange: you seem to rely on the fact that the flags are
> enabled enabled by default, and to disable them one by one.
> 
> If there are more flags at some time, it seems even stranger: the first run
> will have flag1+flag2+flag3, the second only flag2+flag3, the third only
> flag3.
> 
> Is this on purpose?

The intent is for flags to be listed so that if A implies B, A comes first. So AVX2 would come before SSE42 and SSE42 comes before SSE2, etc... So you end up running every variant of the function that runs on your CPU. I'm not particularly attached to this method, but it gets the job done.

This gets a little bit awkward around AESNI and AVX, since there are some AVX CPUs that don't support AESNI, but it would only matter if we had one version of a function that used AVX and not AESNI, and another version that used AESNI and not AVX, or another version that used both. I don't expect that to become a real problem.

> 
>> +            }
>> +        }
>> +        impl2.lib = "lavu";
>> +        run_implementation(input, output, &impl2, size);
>> +        av_force_cpu_flags(real_flags);
>> +        return;
>> +    }
>> +
>>     if (!sscanf(impl->output, "crc:%x", &outcrc)) {
>>         outlen = strlen(impl->output) / 2;
>>         for (i = 0; i < outlen; i++) {
>> @@ -709,8 +744,8 @@ static void run_implementation(const uint8_t *input, uint8_t *output,
>>     fflush(stdout);
>> }
>> 
>> -#define IMPL_USE(lib, name, symbol, output) \
>> -    { #lib, name, run_ ## lib ## _ ## symbol, output },
>> +#define IMPL_USE(lib, name, symbol, output, ...) \
>> +    { #lib, name, run_ ## lib ## _ ## symbol, output, __VA_ARGS__ },
>> #define IMPL(lib, ...) IMPL_USE_ ## lib(lib, __VA_ARGS__)
>> #define IMPL_ALL(...) \
>>     IMPL(lavu,       __VA_ARGS__) \
>> @@ -727,12 +762,12 @@ struct hash_impl implementations[] = {
>>     IMPL(lavu,     "RIPEMD-128", ripemd128, "9ab8bfba2ddccc5d99c9d4cdfb844a5f")
>>     IMPL(tomcrypt, "RIPEMD-128", ripemd128, "9ab8bfba2ddccc5d99c9d4cdfb844a5f")
>>     IMPL_ALL("RIPEMD-160", ripemd160, "62a5321e4fc8784903bb43ab7752c75f8b25af00")
>> -    IMPL_ALL("AES-128-ECB",aes128,    "crc:ff6bc888")
>> -    IMPL_ALL("AES-192-ECB",aes192,    "crc:1022815b")
>> -    IMPL_ALL("AES-256-ECB",aes256,    "crc:792e4e8a")
>> -    IMPL_ALL("AES-128-CBC",aes128cbc, "crc:0efebabe")
>> -    IMPL_ALL("AES-192-CBC",aes192cbc, "crc:ee2e34e8")
>> -    IMPL_ALL("AES-256-CBC",aes256cbc, "crc:0c9b875c")
>> +    IMPL_ALL("AES-128-ECB",aes128,    "crc:ff6bc888", AV_CPU_FLAG_AESNI)
>> +    IMPL_ALL("AES-192-ECB",aes192,    "crc:1022815b", AV_CPU_FLAG_AESNI)
>> +    IMPL_ALL("AES-256-ECB",aes256,    "crc:792e4e8a", AV_CPU_FLAG_AESNI)
>> +    IMPL_ALL("AES-128-CBC",aes128cbc, "crc:0efebabe", AV_CPU_FLAG_AESNI)
>> +    IMPL_ALL("AES-192-CBC",aes192cbc, "crc:ee2e34e8", AV_CPU_FLAG_AESNI)
>> +    IMPL_ALL("AES-256-CBC",aes256cbc, "crc:0c9b875c", AV_CPU_FLAG_AESNI)
>>     IMPL_ALL("CAMELLIA",   camellia,  "crc:7abb59a7")
>>     IMPL_ALL("CAST-128",   cast128,   "crc:456aa584")
>>     IMPL_ALL("BLOWFISH",   blowfish,  "crc:33e8aa74")
> 
> Does it produce warnings for missing initializers in the other cases?

Nope.

> 
> Regards,
> 
> -- 
>  Nicolas George
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org <mailto:ffmpeg-devel at ffmpeg.org>
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel <http://ffmpeg.org/mailman/listinfo/ffmpeg-devel>


More information about the ffmpeg-devel mailing list