PCIE 64-байтовая однократная транзакция

Я хочу выполнить 64-байтовую транзакцию на PCIe. Я использую процессор Intel i7 9-го поколения.

Я смог выполнить 64-байтную транзакцию записи в память устройства PCIe, сделав ее областью WC, и записал данные следующим образом:

_mm256_store_si256(pcie_memory_address, ymm0); 
_mm256_store_si256(pcie_memory_address+32, ymm1);
_mm_mfence();

Я попробовал 64-байтовое чтение с помощью инструкции:

_mm256_loadu_si256();

Используется как запись, но здесь чтение происходит как чтение 2* 32-байт.

Кто-нибудь может мне с этим помочь? Я хочу сделать 64-байтовое чтение как один пакет.

Я ссылался на документацию Intel по этой ссылке: https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/pcie-burst-transfer-paper.pdf


person Rahul K V    schedule 16.05.2020    source источник
comment
Как следует из названия WC, эта функция предназначена для объединения записи в память. Вы можете найти некоторую информацию о том, как это работает здесь. По сути, у процессора есть пара 64-байтовых регистров, в которых он может буферизовать записи (невременные или в память wc/uc), поэтому несколько отдельных операций записи (в идеале) объединяются в одну транзакцию шины. Буферы не загружаются, и вы не хотите загружать из wc памяти, если это вообще возможно. Возможно, AVX512 позволяет одной 64-байтовой загрузке вызывать одну шинную транзакцию, но я не уверен в этом.   -  person EOF    schedule 16.05.2020
comment
AFAICT, вы сможете заменить _mm256_loadu_si256() на _mm_stream_load_si128(), сохранив при этом память wc. Это должно извлекать 64-байтовую кэш-линию за одну транзакцию в буфер заполнения. Вторая выровненная 32-байтная загрузка из той же кэш-линии не должна вызывать вторую шинную транзакцию, если буфер заполнения не был вытеснен в промежутке (но вы не всегда можете предотвратить это, в зависимости от таких вещей, как чтение для владения несвязанные кэш-линии других процессоров).   -  person EOF    schedule 16.05.2020


Ответы (1)


Как вы, ребята, сказали, я использовал _mm256_stream_load_si256() с памятью wc, теперь я также могу читать 64 байта. Вот как я его использовал

__m256i a =   _mm256_stream_load_si256 ((__m256i*)mem_base + 0);
__m256i b =   _mm256_stream_load_si256 ((__m256i*)mem_base + 1);
_mm_mfence();

Спасибо, ребята, за вашу помощь

person Rahul K V    schedule 18.05.2020
comment
Обратите внимание, что внутри ядра использование регистров XMM/YMM безопасно только внутри kernel_fpu_begin()/kernel_fpu_end();. В противном случае вы незаметно испортите состояние пользовательского пространства. Кроме того, для этого требуется AVX, и без этого будет сбой процессора. - person Peter Cordes; 18.05.2020
comment
я это _mm256_stream_load_si256() в приложении пользовательского пространства, поэтому мне нужно использовать kernel_fpu_begin() / kernel_fpu_end(); . И зачем он нужен? - person Rahul K V; 18.05.2020
comment
О, тогда ваш вопрос не должен быть помечен linux-kernel; Я исправил это для вас. kernel_fpu_begin нужен только в коде ядра. ttthtlc.wordpress.com/2016/12 /17/. Пользовательское пространство, конечно, может запускать инструкции SIMD и с плавающей запятой без какой-либо специальной настройки. - person Peter Cordes; 18.05.2020