Производительность оператора Equal против memcmp для примитивных типов данных

Я использовал функцию memcmp для сравнения 2 целых чисел в моем приложении, критичном к производительности. Я должен был использовать это, кроме использования операторов равенства, так как мне приходится иметь дело с другими типами данных в общем. Однако я заподозрил производительность memcpy для примитивных типов данных и изменил ее на оператор равенства. Однако производительность повысилась.

Я просто сделал несколько простых испытаний следующим образом.

Использование memcmp

#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string.h>

using namespace std;

int main(int argc, char **argv)
{
int iValue1 = atoi(argv[1]);
int iValue2 = atoi(argv[2]);

struct timeval start;
gettimeofday(&start, NULL);

for (int i = 0; i < 2000000000; i++)
{
//              if (iValue1 == iValue2)
if (memcmp(&iValue1, &iValue2, sizeof(int)) == 0)
{
cout << "Hello" << endl;
};
};

struct timeval end;
gettimeofday(&end, NULL);

cout << "Time taken : " << ((end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec)) << " us" << endl;
return 0;
}

Вывод программы был следующим.

sujith@linux-1xs7:~> g++ -m64 -O3 Main.cpp
sujith@linux-1xs7:~> ./a.out 3424 234
Time taken : 13539618 us
sujith@linux-1xs7:~> ./a.out 3424 234
Time taken : 13534932 us
sujith@linux-1xs7:~> ./a.out 3424 234
Time taken : 13599818 us
sujith@linux-1xs7:~> ./a.out 3424 234
Time taken : 13639394 us

Используя оператор равенства

#include <time.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string.h>

using namespace std;

int main(int argc, char **argv)
{
int iValue1 = atoi(argv[1]);
int iValue2 = atoi(argv[2]);

struct timeval start;
gettimeofday(&start, NULL);

for (int i = 0; i < 2000000000; i++)
{
if (iValue1 == iValue2)
//              if (memcmp(&iValue1, &iValue2, sizeof(int)) == 0)
{
cout << "Hello" << endl;
};
};

struct timeval end;
gettimeofday(&end, NULL);

cout << "Time taken : " << ((end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec)) << " us" << endl;
return 0;
}

Вывод программы был следующим.

sujith@linux-1xs7:~> g++ -m64 -O3 Main.cpp
sujith@linux-1xs7:~> ./a.out 234 23423
Time taken : 9 us
sujith@linux-1xs7:~> ./a.out 234 23423
Time taken : 13 us
sujith@linux-1xs7:~> ./a.out 234 23423
Time taken : 14 us
sujith@linux-1xs7:~> ./a.out 234 23423
Time taken : 15 us
sujith@linux-1xs7:~> ./a.out 234 23423
Time taken : 16 us

Может кто-нибудь, пожалуйста, дайте мне знать, работает ли оператор равенства быстрее чем memcmp для примитивных типов данных? Если так, что там происходит? Разве оператор равенства не использует memcmp внутри?

-1

Решение

Микробенчмарки сложно писать.

Цикл в первом случае компилируется в (в g++ -O3):

    movl    $2000000000, %ebx
jmp .L3
.L2:
subl    $1, %ebx
je  .L7
.L3:
leaq    12(%rsp), %rsi
leaq    8(%rsp), %rdi
movl    $4, %edx
call    memcmp
testl   %eax, %eax
jne .L2
; code to do the printing omitted
subl    $1, %ebx
jne .L3
.L7:
addq    $16, %rsp
xorl    %eax, %eax
popq    %rbx
ret

Цикл во втором случае компилируется в

    cmpl    %eax, %ebp
je  .L7
.L2:
addq    $8, %rsp
xorl    %eax, %eax
popq    %rbx
popq    %rbp
ret
.L7:
movl    $2000000000, %ebx
.L3:
; code to do the printing omitted
subl    $1, %ebx
jne .L3
jmp .L2

Обратите внимание, что в первом случае memcmp называется 2000000000 раз. Во втором случае оптимизатор выводит сравнение из цикла, поэтому оно выполняется только один раз. Более того, во втором случае компилятор поместил две переменные целиком в регистры, в то время как в первом случае их нужно поместить в стек, поскольку вы берете их адрес.

Даже если просто посмотреть на сравнение, сравните два intс занимает один cmpl инструкция. С помощью memcmp несет вызов функции и внутренне memcmp скорее всего, потребуются дополнительные проверки.

В этом конкретном случае clang++ -O3 компилирует memcmp одному cmpl инструкция. Тем не менее, если вы используете memcmp,

6

Другие решения


По вопросам рекламы [email protected]