Posted on 2022/10/08, 2:06 PM By admin22
久しぶりにx64アセンブラねたです。あるプロジェクトで組み込み機器の処理高速化の際に思いついたのがレジスタを使った高速繰り返しコピーです。あるバイト列を繰り返してコピーするとき、メモリとレジスタを行き来してコピーしていたものをレジスタのみでコピーすることによりパフォーマンスアップできます。
64bit CPUともなるとレジスタも64bit(8byte)になり、下記はこれを二つ使って16バイトデータを4回繰り返しコピーするプログラムです。(後半8バイトは0)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <memory.h> long int duplicate(unsigned char *src, unsigned char *dst, long int n) { long int ret; __asm__ __volatile__ ( "movq (%2), %%rax\n" "movq 8(%2), %%rdx\n" "leaq (%3), %%rbx\n" "movq %1, %%rcx\n" "start:\n" "movq %%rax, (%%rbx)\n" "movq %%rdx, 8(%%rbx)\n" "addq $16, %%rbx\n" "loop start;" :"=r" (ret) :"r"(n), "r"(src), "r"(dst) :"%rcx", "%rax", "%rdx", "%rbx", "memory" ); return ret; } unsigned char data1[100], data2[100]; int main() { memset(data1, 0, 100); for(int i=0;i<8;i++){ data1[i] = 0x41 + i; } memset(data2, 0, 100); duplicate(data1, data2, 4); for(int i=0;i<16*4;i++){ printf("%02x", data2[i]); if(i%16==15) printf("\n"); } } |
備忘録でした。
Categories: 未分類 タグ: Assembly