Skip to content

Instantly share code, notes, and snippets.

@CandyMi
Created July 7, 2022 17:14
Show Gist options
  • Save CandyMi/2b1685259e87808bab2a5eb890a391dd to your computer and use it in GitHub Desktop.
Save CandyMi/2b1685259e87808bab2a5eb890a391dd to your computer and use it in GitHub Desktop.
测试指令集在不同优化等级下生成汇编代码对比
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#if defined(__AVX__)
#include <immintrin.h>
#endif
#if defined(__SSE2__)
#include <emmintrin.h>
#endif
static void* libc_memcpy(char *dst, const char* src, size_t len) {
return memcpy(dst, src, len);
}
static void* simd_memcpy(char *dst, const char* src, size_t len) {
void *ptr = dst;
#if defined(__AVX__)
while(len >= 32)
{
_mm256_store_si256((__m256i*)dst, (__m256i)*(__m256i*)src);
len -= 32; dst += 32; src += 32;
}
#endif
#if defined(__SSE2__)
while(len >= 16)
{
_mm_storeu_si128((__m128i*)dst, (__m128i)*(__m128i*)src);
len -= 16; dst += 16; src += 16;
}
#endif
while (len >= 8)
{
((int64_t*)dst)[0] = ((const int64_t*)src)[0];
len -= 8; dst += 8; src += 8;
}
while (len >= 4)
{
((int32_t*)dst)[0] = ((const int32_t*)src)[0];
len -= 4; dst += 4; src += 4;
}
while (len >= 2)
{
((int16_t*)dst)[0] = ((const int16_t*)src)[0];
len -= 2; dst += 2; src += 2;
}
if (len)
((char*)dst)[0] = ((const char*)src)[0];
return ptr;
}
static void* normal_memcpy(char *dst, const char* src, size_t len) {
void *ptr = dst;
while (len >= 32)
{
((int64_t*)dst)[0] = ((const int64_t*)src)[0];
len -= 8; dst += 8; src += 8;
((int64_t*)dst)[0] = ((const int64_t*)src)[0];
len -= 8; dst += 8; src += 8;
((int64_t*)dst)[0] = ((const int64_t*)src)[0];
len -= 8; dst += 8; src += 8;
((int64_t*)dst)[0] = ((const int64_t*)src)[0];
len -= 8; dst += 8; src += 8;
}
while (len >= 16)
{
((int64_t*)dst)[0] = ((const int64_t*)src)[0];
len -= 8; dst += 8; src += 8;
((int64_t*)dst)[0] = ((const int64_t*)src)[0];
len -= 8; dst += 8; src += 8;
}
while (len >= 8)
{
((int64_t*)dst)[0] = ((const int64_t*)src)[0];
len -= 8; dst += 8; src += 8;
}
while (len >= 4)
{
((int32_t*)dst)[0] = ((const int32_t*)src)[0];
len -= 4; dst += 4; src += 4;
}
while (len >= 2)
{
((int16_t*)dst)[0] = ((const int16_t*)src)[0];
len -= 2; dst += 2; src += 2;
}
if (len)
((char*)dst)[0] = ((const char*)src)[0];
return ptr;
}
int main(int argc, const char* argv[])
{
/* 测试avx */
const int n1 = 33;
char ymmx_out[] = { [0 ... 32] = 0x0 };
const char ymmx[] = "administrator123administrator123";
simd_memcpy(ymmx_out, ymmx, n1);
printf("simd_memcpy = [%s]\n", ymmx_out);
normal_memcpy(ymmx_out, ymmx, n1);
printf("normal_memcpy = [%s]\n", ymmx_out);
libc_memcpy(ymmx_out, ymmx, n1);
printf("libc_memcpy = [%s]\n", ymmx_out);
/* 测试sse2 */
const int n2 = 16;
char mmx_out[] = { [0 ... 15] = 0x0 };
const char mmx[] = "administrator123";
simd_memcpy(mmx_out, mmx, n2);
printf("simd_memcpy = [%s]\n", mmx_out);
normal_memcpy(mmx_out, mmx, n2);
printf("normal_memcpy = [%s]\n", mmx_out);
libc_memcpy(mmx_out, mmx, n2);
printf("libc_memcpy = [%s]\n", mmx_out);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment