memset ve memcpy ile 16 bit kopyalama

taydin

Timur Aydın
Staff member
Katılım
24 Şubat 2018
Mesajlar
23,321
C standard runtime library içerisinde bulunan memcpy ve memset fonksiyonları normalde byte ile çalışır. Yani bir byte adresi verirsin, kaç byte kopyalanacağını veya kaç byte yazılacağını belirtirsin. Eğer kullanılan işlemci mimarisinde RAM, byte olarak adreslenen bir RAM ise, o zaman içerisinde başka tür veriler bulunan yapılar da kopyalanabilir, çünkü neticede veri tipi ne olursa olsun, bellekte ayrı ayrı byte'lar şeklinde saklanacaktır.

Ama diyelim elimizde 16 bit verilerden oluşan bir array var. Bunu memcpy ile kopyalayınca ne kadar süre tutuyor, özel bir assembly fonksiyonu ile 16 bit kopyalama yaparsak ne kadar sürüyor bakalım.

İşlemci Renesas RA6M2, saat hızı 120 MHz

memcpy 16512 tane 16 bit word, yani 33024 byte kopyalarsam, toplam süre 1.96 ms tutuyor.
memset ile 15996 tane 16 bit word, yani toplam 31992 byte koplalarsam, toplam süre 1.86 ms tutuyor.
 
Şimdi memcpy ve memset in yaptığı aynı işi yapan, ama doğrudan 16 erişim ile çalışan assembly fonksiyonları hazırlayalım. Bu fonksiyonlarla yukarıdaki kopyalamaları yapınca, sürenin kabaca yarı yarıya azaldığını görüyorum.

Bir çok programda buradaki kazanç önemli değildir. Ama eğer ekranda titreme olmaması için saniyede 50 defa ekranı tazelemek gerekiyorsa ve bunun için de sürekli buffer kopyalama yapılması gerekiyorsa, her bir mikrosaniye kazanç artık önemli hale geliyor.

C:
static void memcpy16(void* dest, const void* src, size_t count)
{
    __asm volatile(
            "mov r0, %[in_dest]\n\t"
            "mov r1, %[in_src]\n\t"
            "mov r2, %[in_count]\n\t"
            "memcpy16_loop:\n\t"
            "ldrh r3, [r1], #2\n\t"
            "strh r3, [r0], #2\n\t"
            "subs r2, r2, #1\n\t"
            "bgt memcpy16_loop\n\t"
            :
            : [in_dest] "r" (dest), [in_src] "r" (src), [in_count] "r" (count)
            : "r0", "r1", "r2", "r3"
    );
}

static void memset16(void* dest, uint16_t data, size_t count)
{
    __asm volatile(
            "mov r0, %[in_dest]\n\t"
            "mov r1, %[in_data]\n\t"
            "mov r2, %[in_count]\n\t"
            "memset16_loop:\n\t"
            "strh r1, [r0], #2\n\t"
            "subs r2, r2, #1\n\t"
            "bgt memset16_loop\n\t"
            :
            : [in_dest] "r" (dest), [in_data] "r" (data), [in_count] "r" (count)
            : "r0", "r1", "r2"
    );
}
 
Hatta bu optimizasyon daha da ileriye taşınabilir ve genelleştirilebilir. memcpy ve memset fonksiyonları, işlem yapılacak byte adedini 4'e böler, bu kadar 32 bit word işlemi yapar, sonra kalan değer kadar da byte işlemi yapabilir. Bu durumda toplam kopyalama süresi 4 te birine inebilir.

Ama burada, kullanılan işlemci mimarisine göre dikkat edilmesi gereken bir konu var. Örneğin bazı ARM işlemcilerde, bellek erişiminin doğru olarak align edilmiş olması gerekiyor. 16 bit kopyalama için kaynak ve hedef adreslerinin ikiye tam olarak bölünebiliyor olması, 32 bit optimizasyon yapılacaksa, dörde tam olarak bölünebiliyor olması gerekiyor. Eğer bu temin edilmezse, kullanılan ARM mimarisine bağlı olarak ya yanlış veri alınıp saklanır, ya işlemci daha uzun sürede işi bitirir, yada işlemci doğrudan bir exception üretir ve program çakılır.
 
  • Beğen
Reactions: nt
Bunun için fonksiyon hazır hocam, dorde bolunebilirlik kurali sonu 00 olan ya da dordun kati olan sayilar dorde kalansiz bolunebilir diyor. eger yapilacak islemdeki degeri bu fonksiyona gonderirsek sonrasinda sizin yazdiginiz fonksiyon calistirilir. eger kalan olursa degerden kalan cikarilip bu kadar islemde calisitrilir, kalan son degerlerde memcpy ile yapilir. sizin fonksiyona da sprcpy diyelim, memcpy32 de olabilir. :D
 
Son düzenleme:
  • Beğen
Reactions: nt

Forum istatistikleri

Konular
6,572
Mesajlar
111,616
Üyeler
2,693
Son üye
korfez

Son kaynaklar

Son profil mesajları

hakan8470 wrote on Dede's profile.
1717172721760.png
Dedecim bu gul mu karanfil mi? Gerci ne farkeder onu da anlamam. Gerci bunun anlamini da bilmem :gulus2:
Lyewor_ wrote on hakan8470's profile.
Takip edilmeye başlanmışım :D ❤️
Merhaba elektronik tutsakları...
Lyewor_ wrote on taydin's profile.
Merhabalar. Elektrik laboratuvarınız varsa bunun hakkında bir konunuz var mı acaba? Sizin laboratuvarınızı merak ettim de :)
Lyewor_ wrote on taydin's profile.
Merhabalar forumda yeniyim! Bir sorum olacaktı lcr meterler hakkında. Hem bobini ölçen hemde bobin direnci ölçen bir lcr meter var mı acaba?
Back
Top