As respostas a seguir não devem ser vistas como
gabarito, mas sim como a direção do que era esperado como resposta.
1a)
O processamento ocorre acessando dados em cache. Assim, se o vetor
cabe num bloco de cache o acesso é muito mais rápido,
fazendo com que o número de instruções por segundo
seja grande. Ao aumentarmos o tamanho do vetor teremos que carregar/descarregar
vários blocos de cache, diminuindo portanto o número
de instruções que conseguimos executar por segundo.
1b)
Aqui houve um problema de dupla interpretação. O que eu
queria saber era como determinar experimentalmente qual o tamanho de um
bloco de cache no meu computador, mas a questão permitia também
entender que se queria saber como seria uma política de determinação
do tamanho do bloco na implementação do sistema.
Para a compreensão pretendida
a solução é aplicar o programa do item anterior variando
o tamanho do vetor. No ponto em que houvesse uma quebra na curva de tempo
de execução pelo tamanho do vetor teríamos o número
de bytes que caberia num bloco (o tamanho do vetor naquele ponto).
2a)
São processadores que possuem paralelismo de
pipeline, o
que permite a execução simultânea de instruções
específicas, como uma de load/store, outra sobre inteiro
e outra sobre ponto-flutuante, por exemplo.
2b)
Porque não existe paralelismo de dados infinito e o custo de implementação
dos elementos de processamento dedicados (pipelines) é alto.
Assim, limita-se o grau desses processadores por razões econômicas
e de eficiência.
3a)
Como com os elementos de upper e lowerbroadcast é
possivel implementar chaves que liguem duas entradas a duas saídas,
com todas as combinações úteis possíveis, a
implementação da rede segue o mesmo modelo das demais, com
a exceção de que teriamos sempre apenas um sinal de entrada,
o broadcast seria muito mais facilmente obtido e, finalmente, é
necessário evitar broadcasts indesejáveis através
de uma última linha de chaves que tem apenas uma de suas saídas
conectada a alguma máquina.
3b)
Basta examinar um dos exemplos do
livro do Hwang, considerando, é claro, que temos apenas quatro
elementos e não 16, como aparece no livro.
4a)
A questão aqui é o que significa SIMD e qual a sua relação
com o hardware. Isso implica, na realidade, em entender que um sistema SIMD
exige apenas que se executem as mesmas instruções para dados
distintos, não necessariamente no mesmo ciclo de relógio. Desse modo,
o uso de um thread num sistema SIMD pode ocorrer de forma relativamente
tranquila, sendo os threads equivalentes e disparados simultaneamente.
4b) No
caso de MIMD, como os fluxos de instruções são também
distintos, a programação usando threads e sockets
fica mais fácil, bastando disparar os vários códigos
na forma que for mais conveniente.
5a)
Se não se pode definir relação de dependência
é mais prudente que se considere tais instruções como
sequenciais. Assim, essas instruções formam naturalmente
grãos compostos por elas e as instruções próximas
para as quais não se pode estabelecer independência. O paralelismo
seria, então, determinado pelas condições de Bernstein
aplicadas a esses grãos.
5b)
As relações de dependência já existem naturalmente
no preenchimento de um pipeline pelas instruções de
decisão (dependência de controle). Além delas pode,
eventualmente, surgir relações de dependência de dados
se uma operação de STORE em um posição
de memória for imediatamente seguida por uma de LOAD da mesma
posição, pelas relações de dependência
de dados entre as operações de escrita/execução
dos últimos estágios do pipeline.