рд╡рд┐рдВрдбреЛрдЬ рдХреЗ рд▓рд┐рдП рд▓реЙрдХ-рдлреНрд░реА рд╕реНрдЯреИрдХ



рд╡рд┐рдВрдбреЛрдЬ рдкреНрдпрд╛рд░ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рдерд╛рдЧрдд рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрдХреНрд╕рд░, рд╡рд╛рдХреНрдпрд╛рдВрд╢: "рдореИрдВрдиреЗ рд▓реЗрдЦрдХ рдХреА рдкреБрд╕реНрддрдХ рдирд╣реАрдВ рдкрдврд╝реА рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рдирд┐рдВрджрд╛ рдХрд░рддрд╛ рд╣реВрдВ" рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХрд╛ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред рд╡рд┐рдВрдбреЛрдЬ рдХреЗ рд▓рд┐рдП рдЧрд╣рд░реА рдЬрдбрд╝ рд╡рд╛рд▓реА рдЕрд╡рдорд╛рдирдирд╛ тАЛтАЛрдХреЗ рдмрд╛рд╡рдЬреВрдж, рдХреБрдЫ рдЪреАрдЬреЛрдВ рдХреЛ рдЗрд╕рдореЗрдВ рдмрд╣реБрдд рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдФрд░ рд╣рдо рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗред WinAPI рдХреЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЯреБрдХрдбрд╝реЗ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╡реЗ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ, рд╡рд┐рднрд┐рдиреНрди рдХрд╛рд░рдгреЛрдВ рд╕реЗ, рдФрд░ рдЕрдХреНрд╕рд░ рдЕрд╡рд╛рдВрдЫрдиреАрдп рд░реВрдк рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдП рдЧрдП рд╣реИрдВ, рдПрдХ рд╡реНрдпрд╛рдкрдХ рджрд░реНрд╢рдХреЛрдВ рдХреА рджреГрд╖реНрдЯрд┐ рд╕реЗ рдмрд╛рд╣рд░ рд╣реЛ рдЧрдПред

рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо рд▓реЙрдХ-рдлреНрд░реА рд╕реНрдЯреИрдХ рдХреЗ рдУрдПрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗ рдФрд░ рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рд╕рдордХрдХреНрд╖реЛрдВ рдХреЗ рд╕рд╛рде рдЗрд╕рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВрдЧреЗред



рддреЛ, WinAPI рдореЗрдВ рдХрд╛рдлреА рд╕рдордп рд╕реЗ рдПрдХ рдЧреИрд░-рдмреНрд▓реЙрдХрд┐рдВрдЧ рд╕реНрдЯреИрдХ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдПрдХ рдПрдХрд▓ рд▓рд┐рдВрдХ рдХреА рдЧрдИ рд╕реВрдЪреА ( рдЗрдВрдЯрд░рд▓реЙрдХ рдХреА рдЧрдИ рд╕рд┐рдВрдЧрд▓реА рд▓рд┐рдВрдХреНрдб рд▓рд┐рд╕реНрдЯ ) рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╢реЙрд░реНрдЯ рдХреЗ рд▓рд┐рдП SList рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рдХреА рдПрдХ рд╕реВрдЪреА рдФрд░ рдЗрд╕ рдкрд░ рдвреЗрд░ рдЖрджрд┐рдо рдХреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЕрдкрдиреЗ SList рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╡рд┐рд╡рд░рдг рдореЗрдВ рдЬрд╛рдиреЗ рдХреЗ рдмрд┐рдирд╛, Microsoft рдХреЗрд╡рд▓ рд╕рдВрдХреЗрдд рджреЗрддрд╛ рд╣реИ рдХрд┐ рд╡рд╣ рдкрд░рдорд╛рдгреБ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝реЗрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ, рдЙрддреНрдкрд╛рджрдХрддрд╛ рдмрдврд╝рд╛рдиреЗ рдФрд░ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдЧреИрд░-рдЕрд╡рд░реЛрдзрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред



рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рдмрд╕ рдХрдиреЗрдХреНрдЯреЗрдб рд╕реВрдЪрд┐рдпреЛрдВ рдХреЛ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдореИрдХреНрд╕рд┐рдо рдЦрд┐рдЬрд┐рдиреНрд╕реНрдХреА ( рдЦрд┐рдЬрдореИрдХреНрд╕ ) рдиреЗ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╣реБрдд рдХреБрдЫ рд▓рд┐рдЦрд╛ рд╣реИ рдХрд┐ рд╣реЗрдмреЗ рдкрд░ рд▓реЙрдХ-рдлреНрд░реА рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдкрд░ рд▓реЗрдЦреЛрдВ рдХреА рдЙрдирдХреА рд╕реНрдорд╛рд░рдХреАрдп рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╡рд┐рдВрдбреЛрдЬ 8 рд╕реЗ рдкрд╣рд▓реЗ, 128-рдмрд┐рдЯ рдХреИрд╕ рдСрдкрд░реЗрд╢рди рдирд╣реАрдВ рдерд╛, рдЬреЛ рдХрднреА-рдХрднреА 64-рдмрд┐рдЯ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рд╕рдорд╛рди рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╕рдордп рд╕рдорд╕реНрдпрд╛рдПрдВ рдкреИрджрд╛ рдХрд░рддрд╛ рдерд╛ред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╕реНрд▓рд┐рд╕реНрдЯ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддрд╛ рд╣реИред



рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди



SList рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдЦрд╝рд╛рд╕рд┐рдпрддреЛрдВ рдореЗрдВ MEMORY_ALLOCATION_ALIGNER рд╕реАрдорд╛ рдХреЗ рд╕рд╛рде рд╕реВрдЪреА рдЖрдЗрдЯрдо рдХреЗ рд▓рд┐рдП рдореЗрдореЛрд░реА рд╕рдВрд░реЗрдЦрдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, WinAPI рдореЗрдВ рдЕрдиреНрдп рдЗрдВрдЯрд░рд▓реЙрдХ рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рд▓рдЧрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рд▓рд┐рдП, рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рд╕реВрдЪреА рд╡рд╕реНрддреБрдУрдВ рдХреА рд╕реНрдореГрддрд┐ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп align_malloc / align_free рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред



рдПрдХ рдЕрдиреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛ рдпрд╣ рд╣реИ рдХрд┐ SLIST_ENTRY рдкреНрд░рдХрд╛рд░ рдХреА рдЕрдЧрд▓реА рд╕реВрдЪреА рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рд╕реВрдЪрдХ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдмрд╣реБрдд рд╢реБрд░реБрдЖрдд рдореЗрдВ рд╕реНрдерд┐рдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП : рд╣рдорд╛рд░реЗ рдЕрдкрдиреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдПред



рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдПрдХ C ++ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИ, рдЬреЛ SList рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рджреЗрд╢реА WinAPI рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓рдкреЗрдЯрддрд╛ рд╣реИ:



C ++ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛрдб
template<typename T> class SList { public: SList() { // Let Windows initialize an SList head m_stack_head = (PSLIST_HEADER)_aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT); InitializeSListHead(m_stack_head); //UPD: 22.05.2014, thx to @gridem } ~SList() { clear(); _aligned_free(m_stack_head); } bool push(const T& obj) { // Allocate an SList node node* pNode = alloc_node(); if (!pNode) return false; // Call the object's copy constructor init_obj(&pNode->m_obj, obj); // Push the node into the stack InterlockedPushEntrySList(m_stack_head, &pNode->m_slist_entry); return true; } bool pop(T& obj) { // Pop an SList node from the stack node* pNode = (node*)InterlockedPopEntrySList(m_stack_head); if (!pNode) return false; // Retrieve the node's data obj = pNode->m_obj; // Call the destructor free_obj(&pNode->m_obj); // Free the node's memory free_node(pNode); return true; } void clear() { for (;;) { // Pop every SList node from the stack node* pNode = (node*)InterlockedPopEntrySList(m_stack_head); if (!pNode) break; // Call the destructor free_obj(&pNode->m_obj); // Free the node's memory free_node(pNode); } } private: PSLIST_HEADER m_stack_head; struct node { // The SList entry must be the first field SLIST_ENTRY m_slist_entry; // User type follows T m_obj; }; node* alloc_node() { return (node*)_aligned_malloc(sizeof(node), MEMORY_ALLOCATION_ALIGNMENT); } void free_node(node* pNode) { _aligned_free(pNode); } T* init_obj(T* p, const T& init) { return new (static_cast<void*>(p)) T(init); } void free_obj(T* p) { p->~T(); } };
      
      







рдкреНрд░рджрд░реНрд╢рди рдкрд░реАрдХреНрд╖рдг



рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, "рдЙрддреНрдкрд╛рджрдХреЛрдВ" рдФрд░ "рдЙрдкрднреЛрдХреНрддрд╛рдУрдВ" рдХреЗ рд╕рд╛рде рдПрдХ рдорд╛рдирдХ рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреНрд░рддреНрдпреЗрдХ рдкрд░реАрдХреНрд╖рдг рд░рди рдкрд░, рд╣рдо рдЯрд╛рдЗрдк рдЙрдкрднреЛрдХреНрддрд╛ рдФрд░ рдЯрд╛рдЗрдк рдкреНрд░реЛрдбреНрдпреВрд╕рд░ рдХреЗ рдереНрд░реЗрдб рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд╡рд┐рд╡рд┐рдзрддрд╛ рд▓рд╛рддреЗ рд╣реИрдВред рдЗрд╕реА рд╕рдордп, рдХрд╛рд░реНрдпреЛрдВ рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рднреА рдмрджрд▓ рдЧрдИ, рдХреНрдпреЛрдВрдХрд┐ рдкрд░реАрдХреНрд╖рдг рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдкреНрд░рддреНрдпреЗрдХ "рдирд┐рд░реНрдорд╛рддрд╛" рд╣рдореЗрд╢рд╛ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ 1 рдорд┐рд▓рд┐рдпрди рдХреЗ рдмрд░рд╛рдмрд░ рдХрд╛рд░реНрдпреЛрдВ (рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ) рдХрд╛ рдЙрддреНрдкрд╛рджрди рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдПрди рдХреЗ рдмрд░рд╛рдмрд░ рдЙрддреНрдкрд╛рджрдХ рдзрд╛рдЧреЗ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде, рдиреМрдХрд░рд┐рдпреЛрдВ рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рдПрди * 1 рдПрдо рдереАред



SList рдЯреЗрд╕реНрдЯ рдХреЛрдб
 class test { private: static UMS::SList<int64_t> stack; public: static const char* get_name() { return "MS SList"; } static void producer(void) { for (int i = 0; i != iterations; ++i) { if (!stack.push(++producer_count)) return; } } static void consumer(void) { int64_t value; while (WaitForSingleObject(hEvtDone, 10) != WAIT_OBJECT_0) { while (stack.pop(value)) { ++consumer_count; } } while (stack.pop(value)) { ++consumer_count; } } };
      
      





рдХрдВрдЬреНрдпреВрдорд░ рд╡рд░реНрдХрдлрд╝реНрд▓реЛрдЬрд╝ рдХреЛ рд╕реБрд╕реНрддреА рд╕реЗ рдмрдЪрд╛рдиреЗ рдФрд░ рдЧрд╛рд░рдВрдЯреАрдХреГрдд рдиреАрдВрдж рдореЗрдВ рдардВрдб рди рд╣реЛрдиреЗ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдордиреЗ рдЗрд╡реЗрдВрдЯ- рдЯрд╛рдЗрдк рд╡рд┐рдВрдбреЛрдЬ рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЬрд╝реЗрд╢рди рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛, рддрд╛рдХрд┐ "рдирд┐рд░реНрдорд╛рддрд╛рдУрдВ" рдиреЗ рдЕрдкрдирд╛ рдХрд╛рдо рдЦрддреНрдо рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рд╕реНрдЯреИрдХ рдХреЛ рд╕рд╛рдл рдХрд┐рдпрд╛ред "рдЙрдкрднреЛрдХреНрддрд╛" "рдирд┐рд░реНрдорд╛рддрд╛" рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЬрдм рддрдХ "рдирд┐рд░реНрдорд╛рддрд╛" рдмрдВрдж рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рд╣рдо hEvtDone рдЗрд╡реЗрдВрдЯ рдХреЛ рд╕рдХреНрд░рд┐рдп рдХрд░рддреЗ рд╣реИрдВ, рд╡реЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕реНрдЯреИрдХ рд╕реЗ рдХреБрдЫ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░рддреЗ рд╣реИрдВред



рдиреАрдЪреЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ рдЖрд╡рд╢реНрдпрдХ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде рд╣рдорд╛рд░реЗ рдкрд░реАрдХреНрд╖рдг рдХреЛ рдХреЙрд▓ рдХрд░рддрд╛ рд╣реИ:



рдЗрд╕рд▓рд┐рдП рд╣рдо рдкрд░реАрдХреНрд╖рдг рдХрд╣рддреЗ рд╣реИрдВ
 template<typename T> void run_test(int producers, // Number of producer threads int consumers // Number of consumer threads ) { using namespace std; boost::thread_group producer_threads, consumer_threads; // Initiate a timer to measure performance boost::timer::cpu_timer timer; cout << T::get_name() << "\t" << producers << "\t" << consumers << "\t"; // Reset the counters after the previous test producer_count = consumer_count = 0; done = false; ResetEvent(hEvtDone); // Start all the producer threads with a given thread proc for (int i = 0; i != producers; ++i) producer_threads.create_thread(T::producer); // Start all the consumer threads with a given thread proc for (int i = 0; i != consumers; ++i) consumer_threads.create_thread(T::consumer); // Waiting for the producers to complete producer_threads.join_all(); done = true; SetEvent(hEvtDone); // Waiting for the consumers to complete consumer_threads.join_all(); // Report the time of execution auto nanoseconds = boost::chrono::nanoseconds(timer.elapsed().user + timer.elapsed().system); auto seconds = boost::chrono::duration_cast<boost::chrono::milliseconds>(nanoseconds); auto time_per_item = nanoseconds.count() / producer_count; cout << time_per_item << "\t" << seconds.count() << endl; }
      
      





рдкрд░реАрдХреНрд╖рдг рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдЪрд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛:







рджреЛ рдЖрдпрд╛рдореЛрдВ рдореЗрдВ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рднрд┐рдиреНрдирддрд╛рдПрдВ (рдЙрдкрднреЛрдХреНрддрд╛, рдирд┐рд░реНрдорд╛рддрд╛) рд╣рдореЗрдВ рдлрд╝рдВрдХреНрд╢рди рдЯреА (рдкреА, рд╕реА) рджреЗрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдЧреНрд░рд╛рдл рдмрд╛рдИрдВ рдУрд░ рдХреА рдЫрд╡рд┐ рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред



рд╣рдорд╛рд░реА рдЖрдВрдЦреЛрдВ рдХреЗ рд╕рд╛рде рдкрд░рд┐рдгрд╛рдореЛрдВ рдореЗрдВ рд╢реВрдиреНрдп рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЧрдгрдирд╛ рдирд╣реАрдВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдЧрд┐рдирдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд╣рдо рдиреИрдиреЛрд╕реЗрдХрдВрдб рдореЗрдВ рдПрдХ рдХрд╛рд░реНрдп рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордп рджреЗрддреЗ рд╣реИрдВ, рдЬреЛ рдХреБрд▓ рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рд╕рдордп рдХреЗ рд░реВрдк рдореЗрдВ рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИред рдпрд╣ рдорд╛рди рдЬрд┐рддрдирд╛ рдХрдо рд╣реЛрддрд╛ рд╣реИ, рдЙрддрдиреА рд╣реА рддреЗрдЬреА рд╕реЗ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред



рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рдзрд╛рдЧреЗ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреНрд░рдо рдореЗрдВ рдмрджрд▓ рдЧрдИ:
 int NumThreads[] = { 2, 4, 8, 12, 16, 20, 24, 32, 36, 48, 56, 64, 72 };
      
      







рдЗрд╕ рдзрд░рд╛рддрд▓ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВред рдХрдо рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдЙрдкрднреЛрдХреНрддрд╛рдУрдВ (рднреВрдЦрдВрдб рдХреНрд╖реЗрддреНрд░, рд╣рд░реЗ рд░рдВрдЧ рдореЗрдВ рдЪрд┐рддреНрд░рд┐рдд) рдХреЗ рд╕рд╛рде рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд░реВрдк рд╕реЗ рдЧрдВрднреАрд░ рддреНрд╡рд░рдгред рджреЛрдиреЛрдВ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреНрд░рд╡рд╛рд╣ рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдФрд░ рд╡реГрджреНрдзрд┐ рд╕реЗ рдХрд╛рдо рдХреА рдЧрддрд┐ рдореЗрдВ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рд╕реВрдЪрдХ "рд╕рдВрдХреАрд░реНрдг" рдХреБрдЫ рд╕рдВрдХреАрд░реНрдг рдЧрд▓рд┐рдпрд╛рд░реЗ рдореЗрдВ рддреИрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЧреНрд░рд╛рдл рдПрдХ рд╢рд╛рдВрдд рдирд╛рд░рдВрдЧреА рдЯреЛрди рдХреЛ рдмрд░рдХрд░рд╛рд░ рд░рдЦрддрд╛ рд╣реИред



рдпрджрд┐ рд╣рдо рджреВрд╕рд░реЗ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдПрдХ рд╣реА рдЧреНрд░рд╛рдл рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдпрд╣ рд╕реАрдорд╛ рдФрд░ рднреА рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИред рджрд╛рдИрдВ рдУрд░ рдХреА рдЫрд╡рд┐ рдореЗрдВ, рд╣рд░реЗ-рдиреАрд▓реЗ рд░рдВрдЧ рдХреА рдкрдЯреНрдЯреА рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╣реИ, рдкреВрд░реЗ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдЪрд╛рд░ "рдЙрдкрднреЛрдХреНрддрд╛рдУрдВ" рдФрд░ "рдЙрддреНрдкрд╛рджрдХреЛрдВ" рдХреА рдПрдХ рдордирдорд╛рдиреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддреА рд╣реИ, рдЬреЛ рдХрд┐, рдкреНрд░рдпреЛрдЧ рдореЗрдВ рдХреЛрд░ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде рдореЗрд▓ рдЦрд╛рддреА рд╣реИред рдпрд╣ рдиреАрдЪреЗ рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдХрд┐ рдЕрдиреНрдп рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕рдорд╛рди рдЧрддрд┐рд╢реАрд▓рддрд╛ рджрд┐рдЦрд╛рддреЗ рд╣реИрдВред рдпрд╣ Microsoft рджреНрд╡рд╛рд░рд╛ рддреГрддреАрдп-рдкрдХреНрд╖ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдПрд▓реНрдЧреЛрд░рд┐рдердо рдХреА рд╕рдорд╛рдирддрд╛ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реИред



рдпрд╣ рджреЗрдЦрдирд╛ рдЦреБрд╢реА рдХреА рдмрд╛рдд рд╣реИ рдХрд┐ рд▓реЙрдХ-рдлреНрд░реА рдПрдкреНрд░реЛрдЪ рдпрд╣рд╛рдВ рдЕрдкрдиреА рдЪрдордХ рдореЗрдВ рдЪрдордХрддрд╛ рд╣реИ: 72 (+72) рдзрд╛рдЧреЗ рдХреА рдХрд▓реНрдкрдирд╛ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ 1 рдорд┐рд▓рд┐рдпрди рдЯрд╛рд╕реНрдХ рд▓реЙрдХ рдореЗрдВ рд▓рдЯрдХрд╛рдП рдЧрдП рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рд▓реЙрдХ-рдлреНрд░реА рд▓реЗрдЦ рдЖрдорддреМрд░ рдкрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рд╣реЛрддреЗ рд╣реИрдВред



рддреБрд▓рдирд╛



рдирд┐рдореНрди рд▓реВрдк рдореЗрдВ рдЬрд╛рдиреЗ-рдорд╛рдиреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рд╕реЗ рд▓рд┐рдП рдЧрдП рдЧреИрд░-рдЕрд╡рд░реБрджреНрдз рдХрдВрдЯреЗрдирд░реЛрдВ рдХреЗ рджреЛ рдЕрдиреНрдп рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реА рдХрдВрдкреНрдпреВрдЯрд░ рдкрд░ рдПрдХ рд╕рдорд╛рди рдкрд░реАрдХреНрд╖рдг рдЪрд▓рд╛рдпрд╛ рдЧрдпрд╛ рдерд╛:



  int NumThreads[] = { 2, 4, 8, 12, 16, 20, 24, 32, 36, 48, 56, 64, 72 }; for (int p : NumThreads) for (int c : NumThreads) { run_test<lf::boost::test>(p, c); run_test<lf::slist::test>(p, c); run_test<lf::libcds::test>(p, c); }
      
      







рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдХреБрдЫ рд╕рдорд╛рдирддрд╛рдПрдВ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдЗрди рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░реАрдХреНрд╖рдг рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред



Boost.Lockfree рд▓рд╛рдЗрдмреНрд░реЗрд░реА



рдЗрд╕ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдмрдврд╝рд╛рд╡рд╛ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рд╢рд╛рдорд┐рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ ред рдЗрд╕рдореЗрдВ рддреАрди рдХрдВрдЯреЗрдирд░ рд╣реЛрддреЗ рд╣реИрдВ: рдПрдХ рдХрддрд╛рд░, рдПрдХ рд╕реНрдЯреИрдХ рдФрд░ рдПрдХ рд░рд┐рдВрдЧ рдмрдлрд░ред рдЙрдирдХреА рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣рдореЗрд╢рд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрддрд╛ рд╣реИред рдкреНрд░рд▓реЗрдЦрди рд╣реИ рдФрд░ рдЙрджрд╛рд╣рд░рдг рднреАред



рдиреАрдЪреЗ рдмрдврд╝рд╛рд╡рд╛ :: рд╕реНрдЯреИрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдорд╛рди рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдХреЛрдб рд╣реИред

рдмреВрд╕реНрдЯ рдЯреЗрд╕реНрдЯ
 class test { private: static ::boost::lockfree::stack<int64_t> stack; public: static const char* get_name() { return "boost::lockfree"; } static void producer(void) { for (int i = 0; i != iterations; ++i) { while (!stack.push(++producer_count)); } } static void consumer(void) { int64_t value; while (WaitForSingleObject(hEvtDone, 10)!=WAIT_OBJECT_0) { while (stack.pop(value)) { ++consumer_count; } } while (stack.pop(value)) { ++consumer_count; } } };
      
      







рд╣рдо рдЗрд╕ рдкрд░реАрдХреНрд╖рд╛ рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рд░реЗрдЦрд╛рдВрдХрди рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддреЗ рд╣реИрдВ:







рд▓рд┐рдмрдХрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА



рдЗрд╕ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рдЕрдХреНрд╕рд░ рдЕрдкрдиреЗ рд▓реЗрдЦреЛрдВ рдореЗрдВ khizmax рджреНрд╡рд╛рд░рд╛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЕрдкрдиреЗ рдЙрдкрднреЛрдХреНрддрд╛ рдЧреБрдгреЛрдВ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдпрд╣ рд╣рдореЗрдВ рдХреБрдЫ рдмреЛрдЭрд┐рд▓ рдФрд░ рдЦрд░рд╛рдм рджрд╕реНрддрд╛рд╡реЗрдЬ рд▓рдЧрддрд╛ рдерд╛ (рдЕрдзрд┐рдХрд╛рдВрд╢ рдЬрд╛рдирдХрд╛рд░реА рд╣рдо рдпрд╣рд╛рдВ рдкрд░ рдкрд╛рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣реЗ)ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреНрд░рддреНрдпреЗрдХ рдереНрд░реЗрдб рдореЗрдВ рдЬрд╣рд╛рдВ рдЙрдирдХреЗ рд▓реЙрдХ-рдлреНрд░реА рдХрдВрдЯреЗрдирд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдереНрд░реЗрдб рдХреЛ рдЙрдирдХреЗ "рдЗрдВрдЬрди" (рд╢рд╛рдпрдж TLS?) рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдлрд┐рд░ рдЗрд╕реЗ рдЕрд▓рдЧ рдХрд░реЗрдВ рдФрд░ рдЕрднреА рднреА рдХрд╣реАрдВ-рдХрд╣реАрдВ рд╣реЗрдЬрд╝рд░реНрдб рдкреЙрдЗрдВрдЯрд░ рд╕рд┐рдВрдЧрд▓рдЯрди рдХреЛ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред



рд╣рд░ рд╕реНрд╡рд╛рдж рдХреЗ рд▓рд┐рдП рд▓рд╛рдЧреВ рддрд╛рд▓рд╛-рдореБрдХреНрдд рдХрдВрдЯреЗрдирд░реЛрдВ рдХреА рдЕрдХрд▓реНрдкрдиреАрдп рдорд╛рддреНрд░рд╛ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдЗрд╕ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рд╢рд╛рдпрдж рд╣реА рд╕реБрдВрджрд░ рдХрд╣рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ - рдЖрдкрдХреЛ рдЗрд╕рдХреА рдЖрджрдд рдбрд╛рд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред



рдиреАрдЪреЗ рд╕реАрдбреА рдХреЗ рд╕рдорд╛рди рдЯреЗрд╕реНрдЯ рдХреЗ рд▓рд┐рдП рдХреЛрдб рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ :: рдХрдВрдЯреЗрдирд░ :: TreiberStack:

Libcds рдкрд░реАрдХреНрд╖рдг
 class xxxstack : public cds::container::TreiberStack<cds::gc::HP, int64_t> { public: cds::gc::HP hzpGC; xxxstack() { cds::Initialize(0); } }; class test { private: static xxxstack stack; public: static const char* get_name() { return "libcds tb"; } static void producer(void) { // Attach the thread to libcds infrastructure cds::threading::Manager::attachThread(); for (int i = 0; i != iterations; ++i) { //int value = ++producer_count; while (!stack.push(++producer_count)); } // Detach thread when terminating cds::threading::Manager::detachThread(); } static void consumer(void) { // Attach the thread to libcds infrastructure cds::threading::Manager::attachThread(); int64_t value; while (WaitForSingleObject(hEvtDone, 10) != WAIT_OBJECT_0) { while (stack.pop(value)) { ++consumer_count; } } while (stack.pop(value)) { ++consumer_count; } // Detach thread when terminating cds::threading::Manager::detachThread(); } };
      
      







рд╣рдо рдЗрд╕ рдкрд░реАрдХреНрд╖рд╛ рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рд░реЗрдЦрд╛рдВрдХрди рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рддреЗ рд╣реИрдВ:







рдкреНрд░рджрд░реНрд╢рди рдХреА рддреБрд▓рдирд╛



рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдПрд╕рдПрд▓рдЖрдИрдПрд╕ рдПрдХ рджреЗрд╢реА рд╕рдорд╛рдзрд╛рди рд╣реИ, рдФрд░ рдЕрдиреНрдп рджреЛ "рд▓рдЧрднрдЧ" рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рд╣реИрдВ, рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдиреАрдЪреЗ рдХреА рддреБрд▓рдирд╛ рд╡реИрдз рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╕рднреА рдкрд░реАрдХреНрд╖рдг рд╕рдорд╛рди рд╢рд░реНрддреЛрдВ рдХреЗ рддрд╣рдд рдХрд┐рдП рдЧрдП рдереЗ рдФрд░ рдЗрди рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВред



рдкрд░реАрдХреНрд╖рдг рдореЗрдВ рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рд░реИрдЦрд┐рдХ рд╡реГрджреНрдзрд┐ рдХреЗ рдХрд╛рд░рдг рдзрд╛рдЧреЗ рдХреА рд╕рдВрдЦреНрдпрд╛ рдмрдврд╝ рдЬрд╛рддреА рд╣реИ, рд╕рднреА рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рдкреВрд░реНрдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдПрдХ рд╕рднреНрдп рд░рд╛рд╢рд┐ рд▓рдЧрддреА рд╣реИред рдкрд░рд┐рдгрд╛рдо рдХреЛ рд╕реНрдерд┐рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреАрди рдкрд╛рд╕ рдХрд┐рдП рдЧрдП рдереЗ, рдЗрд╕рд▓рд┐рдП рдКрдкрд░ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдП рдЧрдП рдкрд░рд┐рдгрд╛рдо рддреАрди рдкреНрд░рд╛рд░рдВрднреЛрдВ рдХреЗ рдмреАрдЪ рдФрд╕рдд рд╣реИрдВред



рдЙрдкрд░реЛрдХреНрдд рддреАрди-рдЖрдпрд╛рдореА рдЧреНрд░рд╛рдл рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рд╡рд┐рдХрд░реНрдг (рддрд░реНрдХреЛрдВ рдХреЗ рдорд╛рди {p = c}) рд▓рдЧрднрдЧ рдПрдХ рд╕реАрдзреА рд░реЗрдЦрд╛ рд▓рдЧрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рддреАрди рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреА рджреГрд╢реНрдп рддреБрд▓рдирд╛ рдХреЗ рд▓рд┐рдП, рд╣рдордиреЗ рдЗрд╕ рдорд╛рдирджрдВрдб рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХрд╛ рдЪрдпрди рдХрд┐рдпрд╛ред



рдмрд╛рдИрдВ рдУрд░ рдЬреЛ рд╣рдореЗрдВ рдорд┐рд▓рд╛ рд╣реИред



рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдЕрдиреНрдп рджреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдиреЛрдВ рдХреЛ рдмрдврд╝рд╛рд╡рд╛ рджреЗрддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдмрджрд▓рддреЗ рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рдкреНрд░рддрд┐рд░реЛрдз рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред



Libcds рдФрд░ SList рдкрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЗрддрдирд╛ рдЕрдзрд┐рдХ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдкреВрд░реЗ рдЗрдирдкреБрдЯ рдЕрдВрддрд░рд╛рд▓ рдореЗрдВред



рдирд┐рд╖реНрдХрд░реНрд╖



рдпрд╣ рдорд╛рдирд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЗрд╕ рдмрд╛рд░ Microsoft рдиреЗ рдПрдХ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди (рдХреЗрд╡рд▓ рдПрдХ рдХрдВрдЯреЗрдирд░) рдмрдирд╛рдпрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдЬреНрдЮрд╛рдд рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рд╕реЗ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд╛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдореБрдХрд╛рдмрд▓рд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдпрджреНрдпрдкрд┐ рд╡рд░реНрдгрд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдирд╣реАрдВ рд╣реИ, рдпрд╣ рд╡рд┐рдВрдбреЛрдЬ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред



рдпрд╣рд╛рдВ рд╢реНрд░рд╡реНрдп рджреГрд╢реНрдп рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рд╕рд╛рде рд╕рдВрдЧреНрд░рд╣ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВ



рд╕рд╛рдордЧреНрд░реА рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛


рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рддрд╕реНрд╡реАрд░

MSDN slist рд╡рд┐рд╡рд░рдг

Boost.lockfree рдкреБрд╕реНрддрдХрд╛рд▓рдп

рд▓рд┐рдмрдХрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА

рд▓реЙрдХ-рдлреНрд░реА рдбреЗрдЯрд╛ рд╕реНрдЯреНрд░рдХреНрдЪрд░реНрд╕ред рдвреЗрд░ рдХрд╛ рд╡рд┐рдХрд╛рд╕

рдПрд╕рдПрд▓рд╕реНрдЯ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рд╡рд░рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА



рдпреБрдкреАрдбреА:

Mickey99 рдХреЗ рдЕрдиреБрд░реЛрдз рдкрд░ , рд╣рдордиреЗ рдПрдХ рдФрд░ рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛: рдЗрд╕ рдмрд╛рд░ рд╣рдордиреЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдПрд╕рдЯреАрдбреА :: рд╕реНрдЯреИрдХ рд▓рд┐рдпрд╛, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕рд╛рдорд╛рдиреНрдп рдПрд╕рдЯреАрдбреА рджреНрд╡рд╛рд░рд╛ рдЕрд╡рд░реБрджреНрдз рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ :: рдореНрдпреВрдЯреЗрдХреНрд╕ред

рдореНрдпреВрдЯреЗрдХреНрд╕ рдЯреЗрд╕реНрдЯ
 class test { private: static std::stack<int64_t> stack; static std::mutex lock; public: static const char* get_name() { return "mutex"; } static void producer(void) { for (int i = 0; i != iterations; ++i) { lock.lock(); stack.push(++producer_count); lock.unlock(); } } static void consumer(void) { int64_t value; while (WaitForSingleObject(hEvtDone, 10) != WAIT_OBJECT_0) { lock.lock(); if (!stack.empty()) { value = stack.top(); stack.pop(); ++consumer_count; } lock.unlock(); } bool isEmpty = false; while (!isEmpty) { lock.lock(); if (!(isEmpty = stack.empty())) { value = stack.top(); stack.pop(); ++consumer_count; } lock.unlock(); } } };
      
      







рдЪрд▓реЛ рдареАрдХ рд╣реИ: рдореБрдЭреЗ рдПрдХ рд▓рдВрдмрд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд░рдирд╛ рдкрдбрд╝рд╛, рдПрдХ рдмрд╣реБрдд рд▓рдВрдмрд╛ рд╕рдордпред рддрдм рдкреНрд░рддрд┐ рд╕реНрдЯреНрд░реАрдо рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ 1 рдорд┐рд▓рд┐рдпрди рд╕реЗ рдШрдЯрд╛рдХрд░ 100K рдХрд░ рджреА рдЧрдИ рдереА, рдЬрд┐рд╕рд╕реЗ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЗрддрдиреЗ рд╕рдЯреАрдХ рдкрд░рд┐рдгрд╛рдо рдирд╣реАрдВ рдЖрдП (рдЗрд╕ рддрд░рд╣ рдХреА рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ), рдФрд░ рдЗрдирдкреБрдЯ рдзрд╛рд░рд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд▓рд┐рдП рд╕реЗрдЯ рдХреЛ рдмрджрд▓ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рддрд╛рдХрд┐ рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдХрдо рдЕрдВрдХ рдЖрдП :

 int NumThreads[] = { 2, 4, 8, 16, 32, 64};
      
      







рдпрд╣рд╛рдБ рдкрд░рд┐рдгрд╛рдо рд╣реИрдВ:








рдкрд░рд┐рдгрд╛рдо рдмрд╣реБрдд рд╕рдВрдХреЗрдд рд╣реИ: рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд┐рд╕реА рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ 4 рд╕реЗ рдЕрдзрд┐рдХ рдкреНрд░рд╡рд╛рд╣ рдХреЗ рд╕рд╛рде, рд╡реЛрд▓реНрдЯреЗрдЬ рдирд╛рдЯрдХреАрдп рд░реВрдк рд╕реЗ рдмрдврд╝ рдЬрд╛рддрд╛ рд╣реИ, рдкрд░рд┐рдорд╛рдг рдХреЗ рдЖрджреЗрд╢реЛрдВ рджреНрд╡рд╛рд░рд╛ред рдЗрд╕ рддрд░рд╣ рдХреА рд▓рд╛рдЗрди рдкрд╣рд▓реЗ рддреАрди рд╕реЗ рдЪрд╛рд░реНрдЯ рдкрд░ рд╕рд╛рдЬрд┐рд╢ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИред рд╕рдВрднрд╡рддрдГ рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдПрдХ рд▓рдШреБрдЧрдгрдХреАрдп рдкреИрдорд╛рдиреЗ рдХреЗ рд╕рд╛рде рд╣реЛрдЧрд╛ред



All Articles