Respostas:
Na verdade, existem várias razões.
Primeiro e provavelmente acima de tudo, os dados armazenados no cache de instruções geralmente são um pouco diferentes dos armazenados no cache de dados - junto com as próprias instruções, há anotações para coisas como onde a próxima instrução começa, para ajudar os decodificadores. Alguns processadores (por exemplo, Netburst, alguns SPARCs) usam um "cache de rastreamento", que armazena o resultado da decodificação de uma instrução em vez de armazenar a instrução original em sua forma codificada.
Segundo, simplifica um pouco os circuitos - o cache de dados precisa lidar com leituras e gravações, mas o cache de instruções trata apenas de leituras. (Isso é parte do motivo pelo qual o código de modificação automática é tão caro - em vez de sobrescrever diretamente os dados no cache de instruções, a gravação passa pelo cache de dados para o cache L2 e, em seguida, a linha no cache de instruções é invalidada e re carregado de L2).
Terceiro, aumenta a largura de banda: a maioria dos processadores modernos pode ler dados do cache de instruções e do cache de dados simultaneamente. A maioria também tem filas na "entrada" do cache, para que eles possam realmente fazer duas leituras e uma gravação em qualquer ciclo.
Quarto, ele pode economizar energia. Embora você precise manter a energia das próprias células de memória para manter seu conteúdo, alguns processadores podem / desligam alguns dos circuitos associados (decodificadores e outros) quando não estão sendo usados. Com caches separados, eles podem ligar esses circuitos separadamente para obter instruções e dados, aumentando as chances de um circuito permanecer sem energia durante um determinado ciclo (não tenho certeza se algum processador x86 faz isso - AFAIK, é mais um ARM coisa).
Assim como no setor imobiliário, o uso do cache é impulsionado por três coisas: local, local, local. O ponto principal de ter um cache é que a maioria dos programas exibe padrões de localização: se eles acessam o byte 1111111, o próximo byte a que eles acessam é provavelmente 1111110 ou 1111112, e não o byte 9999999. No entanto, a maioria dos programas exibe muito diferentes. padrões de localização para suas instruções e dados. Isso significa que é improvável que as instruções e os dados possam compartilhar o cache com eficiência. Porque instruções e dados não estão necessariamente próximos um do outro na memória. Um acesso a dados coletaria instruções do cache e as instruções de carregamento coletariam dados do cache.