Como faço intencionalmente ler da memória principal vs cache?
-
22-08-2019 - |
Pergunta
Então, eu estou sendo ensinado montagem e temos uma tarefa que é encontrar a diferença de tempo entre a leitura de memória e leitura do cache. Temos que fazer isso criando 2 loops e cronometrando-los. (Lê-se da memória principal e outra de cache). A coisa é, eu não sei e não consigo encontrar nada que me diz como ler a partir de qualquer cache ou memória principal = /. Vocês poderiam me ajudar? Estou fazendo isso em masm32. Eu entendo como fazer loops e assim a maior parte da linguagem de montagem, mas eu simplesmente não posso fazê-lo ler = /
Editar:
Eu tenho uma pergunta, eu fiz isso ...
mov ecx, 100 ;loop 100 times
xor eax, eax ;set eax to 0
_label:
mov eax, eax ;according to me this is read memory is that good?
dec ecx ;dec loop
jnz _label ;if still not equal to 0 goes again to _label
... isso seria ok?
Editar 2:
bem, então, eu não pretendo de alavanca e eu aprecio sua ajuda, eu só tenho outra pergunta, uma vez que estes são dois laços que tenho que fazer. Eu preciso compará-los de alguma forma, eu fui à procura de uma instrução do temporizador, mas eu não encontrei nenhum que eu encontrei apenas: timeGetTime , GetTickCount e Contador de desempenho , mas tanto quanto eu entendo estas instruções retornar a hora do sistema não o tempo que leva para o loop ao fim. Existe uma maneira de realmente fazer o que eu quero? ou eu preciso pensar de outra maneira?
Além disso, para ler de diferentes registros no segundo loop (o que não leitura do cache) é ok se eu der vários "mov" instruções? ou eu estou totalmente fora da base aqui?
Desculpe para todas estas questões, mas mais uma vez obrigado por sua ajuda.
Solução
Para ler a partir do cache. tem um loop que lê a partir do mesmo (ou muito semelhante) de endereço de memória:
- A primeira vez que você ler a partir desse endereço, os valores desse endereço de memória (e de outros, endereço de memória próximo) será movido para o cache
- O próxima vez que você ler a partir desse mesma endereço, os valores já são armazenados em cache e assim você está lendo a partir do cache.
Para ler a memória sem cache, tem um loop que lê muitos, muito diferente (ou seja, mais distante do que o tamanho do cache) endereços de memória.
Para responder à sua segunda pergunta:
-
As coisas que você está fazendo com ecx e JNZ olhar OK (Eu não sei como exato / sensível seu temporizador é, mas você pode querer fazer um loop mais de 100 vezes)
-
O
mov eax, eax
não é "memória de leitura" ... é um não-op, que se move EAX em eax. Em vez disso, eu acho que a sintaxe MASM para a leitura da memória é algo mais parecido commov eax,[esi]
( "ler a partir da posição de memória cujo endereço está contido emesi
") -
Dependendo do que O / S você está usando, você deve ler a partir de um endereço de memória que realmente existe e é legível. No Windows, por exemplo, uma aplicação não seria permitido fazer
mov esi, 0
seguido pormov eax, [esi]
porque um aplicativo não tem permissão para ler a memória cujo endereço / localização é zero.
Para responder à sua terceira pergunta:
timeGetTime, GetTickCount e contador de desempenho
Seu mencionar timeGetTime, GetTickCount e contador de desempenho implica que você está em execução no Windows.
Sim, estes retorno a hora atual, a várias resoluções / precisões: por exemplo, GetTickCount tem uma resolução de cerca de 50 ms, por isso deixa de eventos de tempo que duram menos de 50 ms, é impreciso quando os eventos de tempo que duram apenas 50-100 ms. É por isso que eu disse que 100
em sua ecx
provavelmente não é grande o suficiente.
A função QueryPerformanceCounter
é provavelmente o temporizador mais precisa que você tem.
Para usar qualquer um desses timers como um temporizador de intervalo:
- Obter o tempo, antes de começar a fazer um loop
- Obter o tempo outra vez, depois de terminar looping
- Subtrair estas duas vezes: a diferença é o tempo de intervalo
é ok se eu der várias instruções "mov"?
Sim, eu penso assim. Eu acho que você pode fazê-lo assim (cuidado não tenho certeza / não me lembro se esta é a sintaxe MASM direita para ler a partir de um local de memória nome) ...
mov eax,[memory1]
mov eax,[memory2]
mov eax,[memory3]
mov eax,[memory4]
mov eax,[memory5]
... onde memory1
através memory5
são endereços de variáveis ??globais amplamente espaçados em seu segmento de dados.
Ou, você poderia fazer ...
mov eax,[esi]
add esi,edx
mov eax,[esi]
add esi,edx
mov eax,[esi]
add esi,edx
mov eax,[esi]
add esi,edx
mov eax,[esi]
... onde esi está apontando para o fundo de um longo pedaço de memória, e EDX é algum incremento Isso equivale a cerca de um quinto do comprimento do pedaço.