2013-11-11 1 views
10

Я читаю блог preshing в Memory Reordering Caught in the Act и воспроизведено памяти-переназначения его example codeПочему Go не показывает переупорядочение памяти?

Тогда мне интересно, если я мог воспроизвести память-переназначение с Go, поэтому я написал пример код в ходе, но память переназначение не показано в Go.

Я пишу, чтобы поделиться некоторыми выводами.

И не могли бы вы объяснить, почему Go не может получить переупорядочение памяти? Благодарю.

Пример код в Go:

package main 

    import (
      "fmt" 
      "math/rand" 
    ) 

    var x, y, r1, r2 int 
    var detected = 0 

    func randWait() { 
      for rand.Intn(8) != 0 { 
      } 
    } 

    func main() { 
      beginSig1 := make(chan bool, 1) 
      beginSig2 := make(chan bool, 1) 
      endSig1 := make(chan bool, 1) 
      endSig2 := make(chan bool, 1) 
      go func() { 
        for { 
          <-beginSig1 
          randWait() 
          x = 1 
          r1 = y 
          endSig1 <- true 
        } 
      }() 
      go func() { 
        for { 
          <-beginSig2 
          randWait() 
          y = 1 
          r2 = x 
          endSig2 <- true 
        } 
      }() 
      for i := 1; ; i = i + 1 { 
        x = 0 
        y = 0 
        beginSig1 <- true 
        beginSig2 <- true 
        <-endSig1 
        <-endSig2 
        if r1 == 0 && r2 == 0 { 
          detected = detected + 1 
          fmt.Println(detected, "reorders detected after ", i, "iterations") 
        } 
      } 
    } 

Узел Код (по "ndisasm -b 32") показывает, отличается от C++ против Go

  • Ассемблера кода из C++

    00000CF0 C705520300000100 mov dword [0x352],0x1  //X=1 
         -0000 
    00000CFA 8B0550030000  mov eax,[0x350]  
    00000D00 89054E030000  mov [0x34e],eax  //r1=Y 
    
  • Код сборки от Go

    000013EA 48    dec eax 
    000013EB C70425787F170001 mov dword [0x177f78],0x1  //x=1 
         -000000 
    000013F6 48    dec eax 
    000013F7 8B1C25807F1700 mov ebx,[0x177f80] 
    000013FE 48    dec eax 
    000013FF 891C25687F1700 mov [0x177f68],ebx   //r1=Y 
    00001406 48    dec eax 
    

кажется Go использует dec eax вокруг доступа совместно используемой памяти, но это не имеет смысла, что dec eax может предотвратить память переназначения

  1. Intel® 64 and IA-32 Architectures Software Developer Manuals Том 3, Раздел 8.2 показывает случаи, которые могли бы предотвращение переупорядочения памяти, но dec eax не включен ...

  2. Я попытался добавить dec eax в качестве поля доступа с общей памятью в коде C и в памяти заказ все еще существует.

К настоящему времени я не имею ни малейшего представления о причине. Пожалуйста, помогите мне, спасибо.

ответ

8

Я не вижу вызова для установки GOMAXPROC в любом месте? Если вы не вызываете его вы будете работать только на один процессор, который никогда не будет показывать переупорядочивать: http://golang.org/pkg/runtime/#GOMAXPROCS

Update: В Go 1.5 (выход 2015/08/19), а затем вам не дольше нужно установить GOMAXPROCS - Go по умолчанию использовать все ваши процессоры.

+0

Спасибо, @ Ник. Я пропустил GOMAXPROC ... Идите с переупорядочением памяти после добавления GOMAXPROCS. –

0

Модель памяти Go не относится к C или C++.

Посмотрите на http://golang.org/ref/mem, где описывается отношение «Happens Before» HB и как оно относится к каналам. Обратите внимание, что текущие реализации могут иметь больше HB, чем требуется моделью памяти.

0

Я считаю, что инструкция mov ebx,[0x177f80] делает разницу.

Он загружает ebx, что означает, что mov [0x177f68],ebx зависит от него и не может быть перемещен впереди него. Поэтому, если есть переупорядочение, оба перемещения, которые используют ebx, должны быть переупорядочены вместе. Я думаю, что это не разрешено - архитектор x86_64 не переупорядочивает чтения с другими чтениями (на 100% не уверен).

+0

спасибо, @ugoren. Вы правы, что чтение не переупорядочивается с другими чтениями в архитектуре x86. Здесь переупорядочение происходит между 'mov dword [0x177f78], 0x1' и 'mov [0x177f68], ebx', один из которых читается после одной записи. –

Смежные вопросы