在C中实现strcpy函数

时间:2013-10-10 20:17:54

标签: c performance optimization strcpy

我的任务是这样的:我需要在以下约束条件下实现strcpy函数:

  1. 该函数不能超过七个语句。
  2. 它应该尽可能快。
  3. 它应该使用最少的内存量。
  4. 在将调用我的strcpy的函数中,将保留目标地址 如下:char* newDestination = NULL;
  5. strcpy函数的原型应为:void myStrcp(void** dst, void* src);
  6. 我推出了这个解决方案,它使用uint64_t复制每个迭代8个字节。如果是这样,我的问题将是:

    1. 有没有比我更好的解决方案 - 如果有,请解释为什么它更好?
    2. 我们运行程序(Windows Vs. Linux)和/或平台的操作系统是否重要?
    3. 我的解决方案(在Windows上):

      #include <stdio.h>
      #include <stdlib.h>
      #include <stdint.h>
      #include <string.h>
      #include <conio.h>
      
      void strCpy(void **dst, void *src);
      
      int main()
      {
          char *newLocation = NULL;
      
          strCpy((void **)&newLocation, "stringToBeCopied");
          printf("after my strcpy dst has the string: %s \n", newLocation);
          free(newLocation);
          getch();
          return 0;
      }
      
      void strCpy(void** dst, void* src)
      {
          // Allocating memory for the dst string
          uint64_t i, length = strlen((char *)src), *locDst =
              (uint64_t *) malloc(length + 1), *locSrc = (uint64_t *) src;
          *dst = locDst;
      
          // Copy 8 Bytes each iteration
          for (i = 0; i < length / 8; *locDst++ = *locSrc++, ++i);
      
          // In case the length of the string is not alligned to 8 Bytes - copy the remainder
          // (last iteration)
          char *char_dst = (char *)locDst, *char_src = (char *)locSrc;
      
          for (; *char_src != '\0'; *char_dst++ = *char_src++);
      
          // NULL terminator
          *char_dst = '\0';
      }
      

1 个答案:

答案 0 :(得分:1)

矢量化确实是关键。沿着同样的想法更好的解决方案是使用SSE / AVX来获得更高效的副本。这当然使程序平台具体化,因为您需要检测支持的最大矢量化。

您还应该解决几个问题:

  1. src / dst的对齐 - 如果您复制的块(在上面的例子中是64位)超过了缓存行,那么由于缓存行分割,HW很可能会产生复制的开销。在较长的向量中,开销可能会变得更大(并且在那里也更频繁)。因此,您可以添加一些初始检查来解决此问题,方法是将头部复制成较小的块,就像处理尾部一样。

  2. src / dst区域是否会发生碰撞?如果是这样,你需要为正确的功能行为提供一个定义(在以块的形式复制时,它变得不那么简单)。

  3. 请注意strcpy和memcpy之间的区别(另请参阅here)。这使得矢量化不那么简单,因此您需要在此定义需求。目前,您的函数可能与经典strcpy中的函数不同,因为您不检查每个块中的空字节。不确定这是否是一个问题。

  4. 代码大小限制不是非常友好(除非你的瓶颈是指令缓存容量或分支可预测性,但这非常先进)。 7个陈述的限制可能意味着你过分思考这个问题:)