[英]How to use pld instruction in ARM
我這樣使用它。
__pld(pin[0], pin[1], pin[2], pin[3], pin[4]);
但是我得到這個錯誤。
undefined reference to `__pld'
我想念什么? 我是否需要包含頭文件或其他內容? 我正在使用ARM Cortex A8,它甚至支持pld指令嗎?
如該答案所示,您可以按照Clark的方式使用內聯匯編器。 __builtin_prefetch
也是一個很好的建議。 要知道的一個重要事實是pld
指令如何在ARM上起作用。 對於某些處理器,它什么也不做。 對於其他人,它將數據帶入緩存。 這僅對讀取操作(或讀取/修改/寫入)有效。 要注意的另一件事是,如果它在您的處理器上可以正常工作,則它將獲取整個緩存行。 因此,獲取pin
數組的示例不需要指定所有成員。
通過確保pld
數據與緩存對齊,您將獲得更高的性能。 另一個問題,通過查看前面的代碼,您只會通過讀取的變量獲得性能。 在某些情況下,您只是在寫管腳陣列。 預取這些項目沒有任何價值。 ARM具有寫緩沖區 ,因此, 寫操作將分批處理,並將自動爆發到SDRAM芯片中。
將所有讀取的數據分組在高速緩存行上將顯示出最大的性能提升; 整個生產線可以使用單個pld
預先完成。 此外,當你未滾環,編譯器將能夠看到這些讀取並會更早如果可能的話,讓他們充滿在緩存中安排它們; 至少對於某些ARM cpus。
另外,您可能會考慮,
__attribute__((optimize("prefetch-loop-arrays")))
本着對另一個問題的公認的回答的精神; 如果編譯器在指定的CPU上有效,則可能已在-O3
處啟用了此功能。
可以使用--param NAME=VALUE
指定各種編譯器選項,這些選項可讓您在內存子系統上向編譯器提供提示。 如果您獲得正確的參數,這可能是非常有效的組合。
prefetch-latency
simultaneous-prefetches
l1-cache-line-size
l1-cache-size
l2-cache-size
min-insn-to-prefetch-ratio
prefetch-min-insn-to-mem-ratio
確保為支持pld
的編譯器指定-mcpu
。 如果一切正確,編譯器應自動為您執行此操作。 但是,有時您可能需要手動進行操作。
供參考,這里是gcc-4.7.3的ARM prefetch loop arrays
代碼激活。
/* 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;
嘗試http://www.ethernut.de/en/documents/arm-inline-asm.html
在GCC中,它可能看起來像這樣:
來自以下示例的示例: http : //communities.mentor.com/community/cs/archives/arm-gnu/msg01553.html和pld的用法:
__asm__ __volatile__(
"pld\t[%0]"
:
: "r" (first) );
您可能要看一下gcc的__builtin_prefetch
。 為了方便起見,我在這里復制了它:
此功能用於通過在訪問數據之前將數據移入緩存來最大程度地減少緩存丟失的延遲。 您可以將對__builtin_prefetch的調用插入到代碼中,這些代碼您知道內存中可能很快將被訪問的數據地址。 如果目標支持它們,則將生成數據預取指令。 如果預取在訪問之前足夠早地完成,則數據將在訪問時存儲在緩存中。
addr的值是要預取的內存地址。 有兩個可選參數,rw和locality。 rw的值是編譯時常數1或0。 一個表示預取正准備對存儲器地址進行寫操作,默認為零表示該預取正准備進行讀操作。 值局部性必須是介於0到3之間的編譯時常量整數。 零值表示數據沒有時間局部性,因此在訪問后不必將其保留在高速緩存中。 值為3表示數據具有高度的時間局部性,應保留在所有可能的緩存級別中。 1和2的值分別表示低或中等程度的時間局部性。 默認值為三。
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); /* ... */ }
如果addr無效,則數據預取不會產生錯誤,但是地址表達式本身必須有效。 例如,如果p-> next不是有效地址,則對p-> next的預取不會出錯,但是如果p不是有效地址,則評估將出錯。
如果目標不支持數據預取,則如果地址表達式包含副作用但不生成其他代碼,並且GCC不會發出警告,則將評估地址表達式。
undefined reference to `__pld'
為了回答有關未定義引用的問題, __pld
是ARM編譯器的內在函數。 請參見《 ARM手冊》中的__pld內在函數 。
也許GCC無法識別ARM內部的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.