Vol. 1 12-13
PROGRAMMING WITH INTEL® SSE3, SSSE3, INTEL® SSE4 AND INTEL® AESNI
Example 12-1. Sketch of MOVNTDQA Usage of a Consumer and a PCI Producer
// P0: producer is a PCI device writing into the WC space
# the PCI device updates status through a UC flag, "u_dev_status" .
# the protocol for "u_dev_status" : 0: produce; 1: consume; 2: all done
mov eax, $0
mov [u_dev_status], eax
producerStart:
mov eax, [u_dev_status] # poll status flag to see if consumer is requestion data
cmp eax, $0 #
jne done # I no longer need to produce
commence PCI writes to WC region..
mov eax, $1 # producer ready to notify the consumer via status flag
mov [u_dev_status], eax
# now wait for consumer to signal its status
spinloop:
cmp [u_dev_status], $1 # did I get a signal from the consumer ?
jne producerStart # yes I did
jmp spinloop # check again
done:
// producer is finished at this point
// P1: consumer check PCI status flag to consume WC data
mov eax, $0 # request to the producer
mov [u_dev_status], eax
consumerStart:
mov; eax, [u_dev_status] # reads the value of the PCI status
cmp eax, $1 # has producer written
jne consumerStart # tight loop; make it more efficient with pause, etc.
mfence # producer finished device writes to WC, ensure WC region is coherent
ntread:
movntdqa xmm0, [addr]
movntdqa xmm1, [addr + 16]
movntdqa xmm2, [addr + 32]
movntdqa xmm3, [addr + 48]
… # do any more NT reads as needed
mfence # ensure PCI device reads the correct value of [u_dev_status]
# now decide whether we are done or we need the producer to produce more data
# if we are done write a 2 into the variable, otherwise write a 0 into the variable
mov eax, $0/$2 # end or continue producing
mov [u_dev_status], eax
# if I want to consume again I will jump back to consumerStart after storing a 0 into eax
# otherwise I am done