Инструкции SSE: какие процессоры могут выполнять атомные операции памяти 16B?

Рассмотрим инструкцию SSE с одним доступом к памяти (одно чтение или одна запись, а не чтение + запись) на процессоре x86. Эта команда обращается к 16 байтам (128 битам) памяти, а доступ к ячейке памяти выравнивается до 16 байтов.

В документе «Технический документ по упорядочению памяти архитектуры Intel® 64» говорится, что для «Инструкций, которые читают или пишут четырехслойное слово (8 байт), адрес которого выровнен по 8-байтовой границе», операция памяти, по-видимому, выполняется как один доступ к памяти независимо от тип памяти.

Вопрос:Существуют ли процессоры Intel / AMD / etc x86, которые гарантируют, что чтение или запись 16 байтов (128 бит), выровненных по границе 16 байтов, выполняются как один доступ к памяти? Так, какой конкретно тип процессора это (Core2 / Atom / K8 / Phenom / ...)? Если вы дадите ответ (да / нет) на этот вопрос,пожалуйста, укажите также метод который использовался для определения ответа - поиск документа в формате PDF, тестирование методом грубой силы, математическое доказательство или любой другой метод, который вы использовали для определения ответа.

Этот вопрос относится к таким проблемам, какhttp://research.swtch.com/2010/02/off-to-races.html

Обновить:

Я создал простую тестовую программу на C, которую вы можете запускать на своих компьютерах. Пожалуйста, скомпилируйте и запустите его на вашем Phenom, Athlon, Bobcat, Core2, Atom, Sandy Bridge или любом другом процессоре с поддержкой SSE2. Благодарю.

// Compile with:
//   gcc -o a a.c -pthread -msse2 -std=c99 -Wall -O2
//
// Make sure you have at least two physical CPU cores or hyper-threading.

#include <pthread.h>
#include <emmintrin.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>

typedef int v4si __attribute__ ((vector_size (16)));
volatile v4si x;

unsigned n1[16] __attribute__((aligned(64)));
unsigned n2[16] __attribute__((aligned(64)));

void* thread1(void *arg) {
        for (int i=0; i<100*1000*1000; i++) {
                int mask = _mm_movemask_ps((__m128)x);
                n1[mask]++;

                x = (v4si){0,0,0,0};
        }
        return NULL;
}

void* thread2(void *arg) {
        for (int i=0; i<100*1000*1000; i++) {
                int mask = _mm_movemask_ps((__m128)x);
                n2[mask]++;

                x = (v4si){-1,-1,-1,-1};
        }
        return NULL;
}

int main() {
        // Check memory alignment
        if ( (((uintptr_t)&x) & 0x0f) != 0 )
                abort();

        memset(n1, 0, sizeof(n1));
        memset(n2, 0, sizeof(n2));

        pthread_t t1, t2;
        pthread_create(&t1, NULL, thread1, NULL);
        pthread_create(&t2, NULL, thread2, NULL);
        pthread_join(t1, NULL);
        pthread_join(t2, NULL);

        for (unsigned i=0; i<16; i++) {
                for (int j=3; j>=0; j--)
                        printf("%d", (i>>j)&1);

                printf("  %10u %10u", n1[i], n2[i]);
                if(i>0 && i<0x0f) {
                        if(n1[i] || n2[i])
                                printf("  Not a single memory access!");
                }

                printf("\n");
        }

        return 0;
}

Процессор у меня в ноутбуке - Core Duo (не Core2). Этот конкретный процессор не проходит тест, он реализует чтение / запись 16-байтовой памяти с детализацией 8 байтов. Выход:

0000    96905702      10512
0001           0          0
0010           0          0
0011          22      12924  Not a single memory access!
0100           0          0
0101           0          0
0110           0          0
0111           0          0
1000           0          0
1001           0          0
1010           0          0
1011           0          0
1100     3092557       1175  Not a single memory access!
1101           0          0
1110           0          0
1111        1719   99975389

Ответы на вопрос(6)

Ваш ответ на вопрос