1 / 15

Лекция 2 : Синхронизация

Лекция 2 : Синхронизация. Механизм Read Copy Update (RCU) Барьеры Примитив CMPXCHG Спинлоки Устройство SLT. Аппаратура. CPU 0. MAU. DAM. Link to CPU 1. Кэш L2. MLT. Кэш L1. VLIW e3m – 300 MHz, 2 cpus, SMP e3s – 500 MHz, 4-16 cpus, NUMA. ALU. TLB. RF. SLT. TLU.

clemon
Télécharger la présentation

Лекция 2 : Синхронизация

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Лекция 2: Синхронизация • Механизм Read Copy Update (RCU) • Барьеры • Примитив CMPXCHG • Спинлоки • Устройство SLT

  2. Аппаратура CPU 0 MAU DAM Link to CPU 1 Кэш L2 MLT Кэш L1 VLIW e3m – 300 MHz, 2 cpus, SMP e3s – 500 MHz, 4-16 cpus, NUMA ALU TLB RF SLT TLU AAU(APB) TIRs Cellar (подвал)

  3. Аппаратура CPU 0 MAU DAM Link to CPU 1 Кэш L2 MLT Кэш L1 VLIW e3m – 300 MHz, 2 cpus, SMP e3s – 500 MHz, 4-16 cpus, NUMA ALU TLB RF SLT TLU AAU(APB) TIRs Cellar (подвал)

  4. Механизм RCU struct page { … struct list_head lru; … }; struct list_head { struct list_head *next, *prev; }; #define INIT_LIST_HEAD (ptr) do { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \ } while (0); container_of() page page page head prev next prev next prev next prev next #define list_entry(ptr, type, member) container_of(ptr, type, member)

  5. Механизм RCU struct page { … struct list_head lru; … }; struct list_head { struct list_head *next, *prev; }; #define INIT_LIST_HEAD (ptr) do { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \ } while (0); container_of() page page page head prev next prev next prev next prev next #define list_entry(ptr, type, member) container_of(ptr, type, member)

  6. Механизм RCU #define list_for_each_entry (pos, head, member) \ for (pos = list_entry((head)->next), typeof(*pos), member); \ &pos->member != (head); \ pos = list_entry(pos->member.next, typeof (*pos), member)) CPU0 CPU1 2 1 void __list_del ( struct list_head *prev, struct list_head *next) { next->prev = prev; prev->next = next; } void __list_add (struct list_head *new, struct list_head *prev, struct list_head *next) { next->prev = new; new->next = next; new->prev = prev; prev->next = new; } Race: 1) list_for_each_entry 2) __list_add

  7. Механизм RCU Использование атомарности операции выравненной записи (IA64, E2K) CPU0 CPU1 2 1 Pointer to start of list Entry Entry void __list_add_rcu (struct list_head *new, struct list_head *prev, struct list_head *next) { new->next = next; new->prev = prev; smp_wmb(); next->prev = new; prev->next = new; } New Entry void __list_del ( struct list_head *prev, struct list_head *next) { next->prev = prev; prev->next = next; }

  8. Барьеры include/asm-e2k/e2k_api.h: #define smp_mb() E2K_WAIT(_all_c) #define smp_rmb() E2K_WAIT(_ld_c) #define smp_wmb() E2K_WAIT(_st_c) include/asm-ia64/system.h: #define smp_mb() ia64_mf() #define smp_rmb() smp_mb() #define smp_wmb() smp_mb() • All • Read • Write #define _ld_c 0x8 #define _st_c 0x4 #define _all_c 0x1 #define E2K_WAIT(num) \ asm volatile (“wait ma_c=%0, fl_c=%1, ld_c=%2, st_c=%3, all_e=%4, all_c=%5” : : “i” (((num) & 0x3f) >> 5), … : “memory”); include/asm-ia64/gcc_intrin.h: #define ia64_mf() \ asm volatile (“mf”:::“memory”)

  9. Барьеры include/asm-e2k/e2k_api.h: #define smp_mb() E2K_WAIT(_all_c) #define smp_rmb() E2K_WAIT(_ld_c) #define smp_wmb() E2K_WAIT(_st_c) include/asm-ia64/system.h: #define smp_mb() ia64_mf() #define smp_rmb() smp_mb() #define smp_wmb() smp_mb() • All • Read • Write #define _ld_c 0x8 #define _st_c 0x4 #define _all_c 0x1 #define E2K_WAIT(num) \ asm volatile (“wait ma_c=%0, fl_c=%1, ld_c=%2, st_c=%3, all_e=%4, all_c=%5” : : “i” (((num) & 0x3f) >> 5), … : “memory”); include/asm-ia64/gcc_intrin.h: #define ia64_mf() \ asm volatile (“mf”:::“memory”) Все это хорошо когда есть много читателей и только один писатель. Атомарности RCU и барьеров недостаточно если писателей больше чем один.

  10. Примитив CMPXCHG CMPXCHG – Compare and Exchange. Примитив предназначен для обеспечения атомарности доступа к области памяти (atomic state transition): 1) Писатели пытаются получить эксклюзивный доступ к области памяти 2) Только один писатель получает эксклюзивный доступ 3) Писатель, получивший доступ, меняет содержимое области памяти 4) После изменения содержимого памяти писатель отдает право экслюзивного доступа другим писателям CMPXCHG – примитив нижнего уровня, реализован на ассемблере, обращается напрямую к аппаратному устройству, обеспечивающему переключение состояний строки кэша shared->exclusive. В архитектуре E2K такое устройство называется SLT.

  11. Примитив CMPXCHG #define _E2K_READ_MAS(addr, mas, type, size_letter, chan_letter) \ ({ \ register type res; \ asm volatile(“ld” #size_letter “,” #chan_letter “ 0x0, [%1] %2, %0“) \ : “=r” (res) \ : “r” ((_e2k_ptr_t) (addr)), \ “i” (mas)); \ res; \ }) #define _E2K_WRITE_MAS(addr, mas, type, size_letter, chan_letter) \ ({ \ asm volatile(“st” #size_letter “,” #chan_letter “ 0x0, [%0] %2, %1“) \ : \ : “r” ((_e2k_ptr_t) (addr)), \ “r” ((type) (val)), \ “i” (mas)); \ })

  12. Примитив CMPXCHG, спинлоки static inline unsigned long __cmpxchg_w (unsigned long old, unsigned long new new, volatile void * ptr) { unsigned long prev; prev = E2K_ATOMIC_LBRACKET_W(ptr, MAS_WAIT_LOCK, 3); if (prev == old) E2K_ATOMIC_RBRACKET_W(ptr, new, MAS_WAIT_UNLOCK, 3b); /* доступ получен */ else E2K_ATOMIC_RBRACKET_W(ptr, prev, MAS_WAIT_UNLOCK, 3b); /* занято */ wmb(); return (prev); } исполнение Critical Section accessing data protected by Spinlock Atomic operation lockval 0->1 Write Barrier lockval = 0 Wait while lockval != 0 Exclusive (CMPXCHG) Shared

  13. Спинлоки /* * Decrement the use count and release all resources for an mm. */ void mmput(struct mm_struct *mm) { if (atomic_dec_and_test(&mm->mm_users)) { exit_aio(mm); exit_mmap(mm); if(!list_empty(&mm->mmlist)) { spin_lock(&mmlist_lock); list_del(&mm->mmlist); spin_unlock(&mmlist_lock); } put_swap_token(mm); mmdrop(mm); } } Спинлок = CMPXCHG + запрет прерываний Вопрос: Зачем нужны спинлоки на однопроцессорной машине?

  14. Ссылки • http://os.lab.sun.mcst.ru/techpapers/gelato2005.pdf • http://www.lab.sun.mcst.ru/honey/elbrus_s/project_docs/hw/mu/SLTopi.html

  15. Вопросы

More Related