gpt4 book ai didi

c - 想要使用 ASM 进行快速 8 字节对齐数组复制而不是 memmove

转载 作者:太空宇宙 更新时间:2023-11-04 01:39:46 27 4
gpt4 key购买 nike

我有一个结构数组,其大小在 8 字节边界内。我需要在数组本身内大块地移动数据,所以我一直在使用 memmove()。它有效,但速度很慢。我认为编译器没有优化一次复制 4 或 8 个字节的函数,因此延迟。

我宁愿做的是使用 int32_t 或 int64_t 变量强制复制。这样,我可以让 memcpy 一次复制 4 或 8 个字节,从而加快速度。这可以正常工作,因为我的结构的大小始终为 8 字节边界。

我想不出在 C 中强制执行此操作的方法。我尝试使用内联汇编来实现,但我不知道如何将操作数指向特定的数组元素。例如,如果我的 ASM 语句一次复制 4 个字节,我需要将数组前进 4 个字节。我不知道该怎么做。这是我的想法:

//here's our 2048 byte struct
typedef struct {
filename[1024];
description[1024];
} RECORD;

//total number of rows, or elements
int row_count = 0;

//create initial record
RECORD *record = (RECORD*)malloc(sizeof(RECORD));

//insert some stuff
strcpy(record->filename,"filename.txt");
strcpy(record->description,"Description of file");

//increment our row count
row_count++;

//now let's add a row
record = (RECORD*)realloc(record,sizeof(RECORD)*(row_count+1));

//duplicate first record
//copy first 4 bytes from "record" to the newly appended row
//obviously this would be a loop copying 4 bytes at a time
//up to the the size of the row, which is 2048 bytes.
__asm__("movl (%1), %%eax; \n\t"
"movl %%eax, (%0); \n\t"
: "=r"(record+row_count) //output
: "r"(record+0) //input
: "%eax" ); //list of registers used

//Don't work. :-(

最佳答案

正如@Vlad 指出的那样,memmovememcpy 通常是高度优化的,如今它们通常使用 SIMD 实现大块,这意味着您应该真正分析您的在花时间优化您认为是瓶颈的东西之前编写代码。

关于您的实际问题:您的副本中没有任何循环,但是,最好一次使用 REP MOVSD 4 字节或 REP MOVSQ on x64 for 8一次字节。但是,看到您的数据是 8 字节对齐的,您甚至可以使用 MMX 进行复制,通过 MOVQ ,一次可以处理 64 位。

当存在重叠和其他有趣的角落情况时,这会变得有点复杂,但从它的声音来看你不应该/不需要它,所以事实上,最好的方法可能是最幼稚的方法(这只是副本,如果您不需要 memmove 的其他语义,这将加快速度):

void MyMemCopy(void* pSrc, void* pDst, int nElements)
{
int64_t* s = (int64_t*)pSrc;
int64_t* d = (int64_t*)pDst;
while(nElements--)
*d++ = *s++;
}

现在编译器可以尽可能以最好的方式对其进行优化,无论是内联还是展开等,并且您没有 ASM 的可移植性问题

关于c - 想要使用 ASM 进行快速 8 字节对齐数组复制而不是 memmove,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7860047/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com