STRCMP优化

问题描述 投票:0回答:1

我给自己设定了优化 C 语言中的 strcmp 函数的任务。我通过两种方式完成了这个任务:

  1. 用汇编语言创建一个新的字符串比较函数。
  2. 使用“内在函数”实现 strcmp 功能,其中字符串由 256 位整数寄存器表示。 编译代码后,我发现执行时间没有达到预期。

strcmp 工作时间为 0.000002 秒 my_strcmp 工作 0.000851 秒 my_strcmp2 工作 0.017444 秒

我非常感谢您关于如何优化 strcmp 函数以实现更快的执行时间的建议。在此上下文中,字符串长度限制为 32 个字符。

编译:nasm -g -f elf64 my_strcmp2.asm -o my_strcmp2.o g++ my_strcmp2.o main.cpp -march=znver3 -O3 -o 应用程序

main.cpp:

#include <stdio.h>
#include <string.h>
#include <time.h>
#include <immintrin.h>

int my_strcmp(const char* word1, const char* word2);
extern "C" int my_strcmp2(const char* word1, const char* word2);
double timer(int (*func)(const char*, const char*));

int main()
{
    int j = 0;
    const char* word1 = "my name is";
    const char* word2 = "my name are";

    clock_t begin = clock();
    for (int i = 0; i < 1000000; i++)
    {
        j = strcmp(word1, word2);
    }
    clock_t end = clock();
    fprintf(stderr, "strcmp     : %lf seconds\n", (double)(end - begin) / CLOCKS_PER_SEC);

    begin = clock();
    for (int i = 0; i < 1000000; i++)
    {
        j = my_strcmp(word1, word2);
    }
    end = clock();
    fprintf(stderr, "my_strcmp  : %lf seconds\n", (double)(end - begin) / CLOCKS_PER_SEC);

    begin = clock();
    for (int i = 0; i < 1000000; i++)
    {
        j = my_strcmp2(word1, word2);
    }
    end = clock();
    fprintf(stderr, "my_strcmp2 : %lf seconds\n", (double)(end - begin) / CLOCKS_PER_SEC);

    return 0;
}

int my_strcmp(const char* word1, const char* word2)
{

    __m256i str_reg_1 = _mm256_lddqu_si256((__m256i*)word1);
    __m256i str_reg_2 = _mm256_lddqu_si256((__m256i*)word2);
    __m256i res_cmp = _mm256_cmpeq_epi8(str_reg_1, str_reg_2);
    int mask = ~_mm256_movemask_epi8(res_cmp);

    return mask;
}

my_strcmp2.asm:

global my_strcmp2
section .text

my_strcmp2:
    cycle:
        cmp byte [rel rdi], 0x00
        je check_equal
        mov dl, byte [rel rsi]
        cmp byte [rel rdi], dl
        jne not_equal
        add rdi, 1
        add rsi, 1
    jmp cycle

    not_equal:
        mov rax, 0x01
        ret

    check_equal:
        cmp byte [rel rsi], 0x00
        jne not_equal
        xor rax, rax
        ret
c assembly intrinsics
1个回答
0
投票

GCC 知道

strcmp
的作用并且可以看到这段代码:

for (int i = 0; i < 1000000; i++)
    {
        j = strcmp(word1, word2);
    }

相当于:

j = strcmp(word1, word2);

因此,它优化了循环,并且每次迭代的时间实际上为零。你不可能用自己的

strcmp
实现来解决这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.