Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在ARM中使用pld指令_C_Gcc_Arm - Fatal编程技术网

C 如何在ARM中使用pld指令

C 如何在ARM中使用pld指令,c,gcc,arm,C,Gcc,Arm,我是这样用的 __pld(pin[0], pin[1], pin[2], pin[3], pin[4]); 但我得到了这个错误 undefined reference to `__pld' 我错过了什么?我需要包含头文件还是什么?我使用的是ARM Cortex A8,它是否支持pld指令?试试看 在GCC中,它可能如下所示: 示例来自: 以及pld的用途: __asm__ __volatile__( "pld\t[%0]" : : "r" (first) );

我是这样用的

__pld(pin[0], pin[1], pin[2], pin[3], pin[4]);
但我得到了这个错误

undefined reference to `__pld'
我错过了什么?我需要包含头文件还是什么?我使用的是ARM Cortex A8,它是否支持pld指令?

试试看

在GCC中,它可能如下所示:

示例来自: 以及pld的用途:

   __asm__ __volatile__(
    "pld\t[%0]"
    :
    : "r" (first) );

你可能想看看gcc的。为了您的方便,我在这里复制了它:

此函数用于通过在访问数据之前将数据移动到缓存中来最小化缓存未命中延迟。您可以在代码中插入对uuu builtin_prefetch的调用,因为您知道内存中可能很快就会被访问的数据的地址。如果目标支持它们,将生成数据预取指令。如果在访问之前足够早地完成预取,那么在访问数据时,数据将在缓存中

addr的值是要预取的内存地址。有两个可选参数,rw和locality。rw的值是编译时常量1或0;一表示预取正在准备写入内存地址,而零(默认值)表示预取正在准备读取。值局部性必须是介于0和3之间的编译时常量整数。值为零意味着数据没有时间局部性,因此访问后不需要将其留在缓存中。值为3表示数据具有高度的时间局部性,应尽可能保留在所有级别的缓存中。1和2的值分别表示时间局部性的低或中等程度。默认值为3

     for (i = 0; i < n; i++)
       {
         a[i] = a[i] + b[i];
         __builtin_prefetch (&a[i+j], 1, 1);
         __builtin_prefetch (&b[i+j], 0, 1);
         /* ... */
       }
(i=0;i { a[i]=a[i]+b[i]; __内置预取(&a[i+j],1,1); __内置预取(&b[i+j],0,1); /* ... */ } 如果addr无效,数据预取不会生成错误,但地址表达式本身必须有效。例如,如果p->next不是有效地址,则p->next的预取将不会出错,但如果p不是有效地址,则评估将出错

如果目标不支持数据预取,则在地址表达式包含副作用但未生成其他代码且GCC未发出警告时,将对其进行计算

如中所示,您可以根据使用内联汇编程序<代码>\内置预取也是一个好建议。需要了解的一个重要事实是
pld
指令如何作用于ARM;对于某些处理器,它什么也不做。对于其他人,它会将数据带到缓存中。这仅对读取操作(或读取/修改/写入)有效。另一件需要注意的事情是,如果它在处理器上工作,它将获取整个缓存线。因此,获取
pin
数组的示例不需要指定所有成员

通过确保
pld
数据与缓存对齐,您将获得更高的性能。另一个问题是,从前面的代码中可以看出,只有使用读取的变量才能获得性能。在某些情况下,您只是写入pin数组。预取这些项目没有任何价值。ARM有一个写缓冲区,因此写操作将一起批处理,并自动突发到SDRAM芯片

将所有读取的数据分组在缓存线上将显示出最大的性能改进;整条生产线可以用一个
pld
进行预匹配。此外,当您取消循环时,编译器将能够看到这些读取,并在可能的情况下提前安排它们,以便将它们填充到缓存中;至少对于一些ARM CPU

也可以考虑,

 __attribute__((optimize("prefetch-loop-arrays")))
本着对另一个问题的公认答案的精神;如果在指定的CPU上有效,编译器可能已经在
-O3
上启用了此功能

可以使用
--param NAME=VALUE
指定各种编译器选项,允许您在内存子系统上向编译器提供提示。如果参数正确,这可能是一个非常有效的组合

  • 预取延迟
  • 同步预取
  • l1缓存线大小
  • 一级缓存大小
  • 二级缓存大小
  • min insn与预取比率
  • 预取最小insn与mem比率
确保为支持
pld
的编译器指定
-mcpu
。如果一切正常,编译器将自动为您执行此操作。但是,有时您可能需要手动执行此操作

以下是gcc-4.7.3的ARM
预取循环数组
代码激活,以供参考

  /* Enable sw prefetching at -O3 for CPUS that have prefetch, and we have deemed
     it beneficial (signified by setting num_prefetch_slots to 1 or more.)  */
  if (flag_prefetch_loop_arrays < 0
      && HAVE_prefetch
      && optimize >= 3
      && current_tune->num_prefetch_slots > 0)
    flag_prefetch_loop_arrays = 1;
/*为具有预取功能的CPU启用-O3的软件预取,我们认为
这是有益的(通过将num_prefetch_slot设置为1或更多表示)*/
如果(标志\u预取\u循环\u数组<0
&&进行预取
&&优化>=3
&&当前\u调谐->数量\u预取\u插槽>0)
flag_prefetch_loop_array=1;
为了回答有关未定义引用的问题,
\uu pld
是ARM编译器的固有特性。请参阅ARM手册中的


也许GCC不认识ARM本质。

什么编译器?这应该是内联汇编程序吗?这取决于你的编译器。PLD是一种汇编指令。例如,请参阅(内置预取)答案是好的。您还应该检查二进制文件是否包含pld指令(使用objdump)。提前几次预加载(pld)内容。您正在读取的地址也应该与缓存线对齐。很难使pld正确。大多数情况下,cpu/core也会为您做这件事。所以你可能看不到这有什么好处。@MetallicPrist我想这就是为什么它被命名为第一名,仅供参考,预回迁并不总是优化事情。@MetallicPrist,我没有真正的想法,但看起来是这样的。%你会喜欢我吗
undefined reference to `__pld'