Test bit için kullanılan bir makro (Linux versiyonu 2.6.2) bulunmaktadır olarak:farkı parametre olarak derleme zaman sabit veya değişken geçen Linux çekirdek kod
static inline int constant_test_bit(int nr, const volatile unsigned long *addr )
{
return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0;
}
static __inline__ int variable_test_bit(int nr, const volatile unsigned long *addr)
{
int oldbit;
__asm__ __volatile__(
"btl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit)
:"m" (ADDR),"Ir" (nr));
return oldbit;
}
Ben __builtin_constant_p
değişken sabit veya bilinmeyen derleme süresi olup olmadığını tespit etmek için kullandığını anlıyoruz. Sorum şu: Bu argüman bir derleme zamanı sabiti olduğunda ya da değilken, bu iki işlev arasında herhangi bir performans farkı var mı? Neden C versiyonunu kullanıyor ve kurulmadığı zaman montaj sürümünü kullanıyorsunuz?
GÜNCELLEME: aşağıdaki ana işlevi performansını test etmek için kullanılır:
sabit, çağrı constant_test_bit:
int main(void) {
unsigned long i, j = 21;
unsigned long cnt = 0;
srand(111)
//j = rand() % 31;
for (i = 1; i < (1 << 30); i++) {
j = (j + 1) % 28;
if (constant_test_bit(j, &i))
cnt++;
}
if (__builtin_constant_p(j))
printf("j is a compile time constant\n");
return 0;
}
Bu doğru cümle j bir çıkışlarının ...
Diğer durumlar için j
'a "rasgele" bir numara atar ve işlev adını ly. Bu hat karşılıksız olduğunda çıktı boş olacak ve bu bekleniyor.
sabit constant_test_bit:
$ time ./a.out
j is compile time constant
real 0m0.454s
user 0m0.450s
sys 0m0.000s
sabit variable_test_bit (aşağıdaki aynı time ./a.out
, atın):
j is compile time constant
real 0m0.885s
user 0m0.883s
sys 0m0.000s
burada derlemek ve
gcc test.c -O1
kullanımı
sonucudur
değişken, sabit_test_bit:
real 0m0.485s
user 0m0.477s
sys 0m0.007s
değişken, variable_test_bit:
real 0m3.471s
user 0m3.467s
sys 0m0.000s
ben her sürümü birkaç kez çalışır var ve yukarıdaki sonuçlar bunlardan tipik değerlerdir. constant_test_bit
işlevinin her zaman variable_test_bit
işlevinden daha hızlı olduğu görülüyor, parametrenin bir derleme zamanı sabiti olup olmadığı farketmez ... Son iki sonuç için (j
sabit değilken) değişkenin sürümü sabitden bile önemli ölçüde daha yavaştır bir. Burada bir şey eksik miyim?Biz iyileştirici aşağıdaki sürekli ifade davayı optimize edebiliyor bkz
// Non constant expression test case
int func1(unsigned long i, unsigned long j)
{
int x = constant_test_bit(j, &i) ;
return x ;
}
// constant expression test case
int func2(unsigned long i)
{
int x = constant_test_bit(21, &i) ;
return x ;
}
:
Olabilir, ancak öğrenmenin tek yolu ölçmektir. – deviantfan
Açıkçası, birisi mükemmel bir fark yarattığını düşünüyordu ya da 2 versiyon olmayacaktı. Ayrıntılar için, göz önünde bulundurulacak 4 vakanız vardır (her iki fonksiyona da bir sabit/sabit olmayan). Her durumda ne olduğunu düşünüyorsunuz? Oluşturulan meclise baktın mı? –
@deviantfan Performans sonuçlarını ekledim. –