σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyRoadmapsRoteiros
Ctrl K
AO
+1,2 mil alunos
EntrarParticipar ↗
RoadmapsRoteiros
AO
+1,2 mil alunos
Entrar
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyRoadmapsRoteiros
Ctrl K
AO
+1,2 mil alunos
EntrarParticipar ↗
RoadmapsRoteiros
AO
+1,2 mil alunos
Entrar
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Roteiro de Cache locality›Módulo 1 · Caches do zero›Tópico 1.4·~45 minIntermediário

Localidade temporal e conjuntos de trabalho

Posição no roteiroMódulo 1 de 3 · Tópico 4 de 4
1.4 Localidade temporal e conjuntos de trabalho
—Nota do lab— / 100XP total—Sequência—

5 min de leitura4 exemplos de código

  1. 01Ler a mesma linha de novo
  2. 02Das distâncias às taxas de acerto
  3. 03Conjuntos de trabalho e o precipício
  4. 04Uma média móvel sobre preços reais
  5. 05O que você vai construir

Um cache só ajuda com dados que você lê de novo, e o que importa é quão cedo. Esta aula mede isso com um único número, a distância de reutilização, e o usa para prever de uma vez a taxa de acertos de todos os tamanhos de cache, incluindo o precipício em que um laço é só um pouco grande demais para caber.

01

Ler a mesma linha de novo

Os dois últimos tópicos trataram de para onde vão as linhas. Este trata de quando elas voltam. Um programa que lê um preço, trabalha um pouco e lê o mesmo preço de novo um instante depois mostra localidade temporal. Quanto menor a lacuna, maior a chance de a linha ainda estar no cache. Pense nos livros da sua mesa: o que você usou há um minuto ainda está lá, o do mês passado voltou para a estante.

DefiniçãoDistância de reutilização

Para uma leitura de uma linha, o número de outras linhas diferentes lidas desde a leitura anterior da mesma linha. A primeira leitura de uma linha não tem distância.

Ler a linha 5 duas vezes seguidas dá distância 0. Na sequência 1, 2, 3, 1 a última leitura tem distância 2, porque as linhas 2 e 3 vieram no meio. Ler dez vezes a linha 2 entre duas leituras da linha 1 ainda conta como uma só linha. O código guarda uma lista das linhas na ordem do último uso, a mais recente por último. Quando uma linha volta, as linhas depois dela na lista são exatamente as usadas desde então.

main.pyPython
def reuse_distances(lines):    stack = []    out = []    for line in lines:        if line in stack:            position = stack.index(line)            out.append(len(stack) - 1 - position)1            stack.pop(position)        else:            out.append(None)        stack.append(line)    return outprint(reuse_distances([1, 2, 3, 1, 2, 1, 1]))
[None, None, None, 2, 2, 1, 0]
  1. 1As linhas depois desta na lista são exatamente as usadas desde a sua última leitura: o número delas é a distância.
02

Das distâncias às taxas de acerto

Eis o fato útil. Pegue um cache que guarda C linhas e remove a menos recentemente usada, sejam quais forem os números das linhas. A cada momento ele guarda as C linhas diferentes usadas mais recentemente. Uma leitura acerta exatamente quando sua linha está entre elas, isto é, quando menos de C linhas diferentes foram lidas desde o último uso. Em outras palavras, a leitura acerta quando sua distância de reutilização é menor que C.

hit ⇔ reuse distance < capacity(1)para um cache LRU totalmente flexível: qualquer linha pode ir para qualquer lugar, então só importa o número de linhas

O código abaixo verifica a afirmação. Ele simula um cache LRU para capacidades de 1 a 4 e também calcula a taxa de acertos só a partir das distâncias, sem cache algum. As duas colunas concordam. As distâncias são calculadas uma vez e depois dão a taxa de acertos de cada tamanho de cache.

main.pyPython
def lru_hit_rate(lines, capacity):    cache = []    hits = 0    for line in lines:        if line in cache:            hits += 1            cache.remove(line)        elif len(cache) >= capacity:            cache.pop(0)        cache.append(line)    return hits / len(lines)def hit_rate_from_distances(distances, capacity):    hits = sum(1 for d in distances if d is not None and d < capacity)    return hits / len(distances)lines = [1, 2, 3, 1, 2, 3, 4, 1, 2, 3]d = reuse_distances(lines)for capacity in (1, 2, 3, 4):    print(capacity, "lines:", round(lru_hit_rate(lines, capacity), 3), round(hit_rate_from_distances(d, capacity), 3))1
1 lines: 0.0 0.0
2 lines: 0.0 0.0
3 lines: 0.3 0.3
4 lines: 0.6 0.6
  1. 1Os mesmos números nas duas colunas: as distâncias sozinhas preveem a taxa de acertos de cada tamanho de cache.
Uma só passada dá todos os tamanhos de cache

Sem as distâncias você teria de rodar um simulador de novo para cada tamanho a testar. Com elas, uma só passada pelo rastro dá toda a curva da taxa de acertos contra o tamanho do cache. Engenheiros de desempenho chamam isso de curva de taxa de faltas.

03

Conjuntos de trabalho e o precipício

O conjunto de trabalho de um trecho de leituras é o conjunto de linhas diferentes que elas tocam. Se cabe no cache, o programa roda quase todo a partir do cache. Se é só um pouco maior, o LRU pode falhar por completo. Pegue um laço que lê 48 linhas em ordem, três vezes. Cada linha é lida de novo depois de outras 47, então toda distância de reutilização é 47. Um cache de 47 linhas ou menos nunca acerta, e um de 48 acerta em toda leitura depois da primeira passada.

main.pyPython
def sweep_lines(n_lines, passes):    return list(range(n_lines)) * passeslines = sweep_lines(48, 3)for capacity in (16, 32, 47, 48):    print(capacity, "lines:", round(lru_hit_rate(lines, capacity), 3))
16 lines: 0.0
32 lines: 0.0
47 lines: 0.0
48 lines: 0.667
Uma linha a menos pode significar zero acertos

A taxa de acertos não cai suavemente quando um laço passa do tamanho do cache. Com LRU e um laço que percorre as mesmas linhas na mesma ordem, ela cai de 0,667 para 0,0 na linha exata em que o conjunto de trabalho deixa de caber. Um programa pode ser rápido com um tamanho de entrada e muitas vezes mais lento com um pouco maior.

04

Uma média móvel sobre preços reais

Uma média móvel calculada do jeito lento lê os últimos 20 valores todo dia: ela relê 19 dos 20 valores lidos no dia anterior. É um programa com muita localidade temporal. O código monta os endereços lidos para os primeiros 600 fechamentos, transforma-os em linhas e mede as distâncias, a taxa de acertos para quatro tamanhos de cache e o conjunto de trabalho de 20 leituras consecutivas.

main.pyPython
def rolling_mean_trace(n, window, elem_bytes):    trace = []    for end in range(window - 1, n):        for position in range(end - window + 1, end + 1):            trace.append(position * elem_bytes)    return tracedef working_set(lines, window):    return max(len(set(lines[i:i + window])) for i in range(len(lines) - window + 1))lines = [address // 64 for address in rolling_mean_trace(600, 20, 8)]d = reuse_distances(lines)print(len(lines), "reads from", len(set(lines)), "lines")for capacity in (1, 2, 4, 8):    print(capacity, "lines:", round(hit_rate_from_distances(d, capacity), 3))print("working set of 20 reads:", working_set(lines, 20), "lines")
11620 reads from 75 lines
1 lines: 0.831
2 lines: 0.831
4 lines: 0.994
8 lines: 0.994
working set of 20 reads: 4 lines

Uma linha basta para 83% das leituras, porque o próximo valor do array está na linha que acabou de ser lida. Quatro linhas chegam a 99,4%. As 75 linhas do conjunto de dados nunca precisam caber: o conjunto de trabalho de 20 leituras é só de 4 linhas, então um cache minúsculo basta. Essa é a diferença entre o tamanho dos dados e o tamanho do conjunto de trabalho.

O que dizem os dados reaisMédia móvel de 20 dias sobre os primeiros 600 fechamentos do SPY
Leituras11,620de 75 linhas diferentes
Conjunto de trabalho de 20 leituras4lineso conjunto de dados inteiro nunca precisa caber
Tamanho de cache para 90% de acertos3lines192 bytes de cache
Varredura de 48 linhas, cache de 32 linhas0.0hitscom 48 linhas: 0,667
Taxa de acertos da média móvel por tamanho de cache, em %
1 linha83.1
2 linhas83.1
4 linhas99.4
8 linhas99.4
05

O que você vai construir

O laboratório pede as peças acima, mais o auxiliar que acha o menor cache para uma taxa de acertos, e termina com o estudo sobre os fechamentos reais do SPY.

  • Função · perguntaBaseia-se em
  • reuse_distances(lines)Quão cedo cada linha é lida de novo?Uma lista em ordem do último uso
  • lru_hit_rate(lines, capacity)Quanto acerta um cache LRU simulado?Linhas em ordem LRU
  • hit_rate_from_distances(distances, capacity)A mesma taxa de acertos, sem cache?reuse_distances
  • working_set(lines, window)Quantas linhas um trecho de leituras toca?Uma janela deslizante
  • capacity_for(lines, target)Quão pequeno o cache pode ser?reuse_distanceshit_rate_from_distances
  • rolling_mean_trace(n, window, elem_bytes)Quais endereços uma média móvel lenta lê?Aritmética simples
  • study(bars)Quão local é uma média móvel sobre os fechamentos do SPY?rolling_mean_tracecapacity_for

Pontos-chave

  • A distância de reutilização prevê os acertos. Um cache LRU de C linhas acerta exatamente as leituras cuja distância é menor que C, então uma passada de distâncias dá a taxa de acertos de cada tamanho.
  • O conjunto de trabalho define o tamanho. O que precisa caber é o conjunto de trabalho de um trecho de leituras, não todos os dados: 4 linhas bastaram para uma tabela de 75 linhas.
  • Cuidado com o precipício. Um laço cujo conjunto de trabalho excede em uma linha um cache LRU pode perder todos os acertos; meça nos tamanhos em que vai rodar.
Verificação rápida
As leituras são as linhas A, B, C, A. Qual é a distância de reutilização do último A?
Escolha uma resposta.

Próximo tópico: agora você sabe como uma disposição vira um rastro e um rastro vira acertos e faltas. Em Array de structs contra struct de arrays você usa isso para escolher como dispor uma tabela de ticks, comparando leituras de colunas e de linhas inteiras nas duas disposições.

Lab: o que é avaliado

7 tarefas · 100 pts
  • Distâncias de reutilização20 pts
  • Um cache LRU simulado15 pts
  • A taxa de acertos a partir das distâncias10 pts
  • O conjunto de trabalho de uma janela15 pts
  • O menor cache10 pts
  • Uma média móvel lenta10 pts
  • O estudo com a tabela do SPY20 pts
Explorador · lab-cl-4
▾ lab-cl-4
▾ data
…
bash · no navegador
learner@quantcraft:~/lab-cl-4$
Python ainda não carregadoPythonLn 1, Col 1Spaces: 4UTF-8

Redefinir este tópico?

Tudo em lab-cl-4 volta aos arquivos iniciais e o terminal é limpo. Sua solução atual será perdida — isso não pode ser desfeito.

Será redefinido
  • main.py → código inicial
  • Histórico do terminal e saída dos testes
  • Alterações não enviadas
Será mantido
  • Melhor nota do lab
  • Seu XP e sua sequência
  • Progresso da aula e anotações