Programação Paralela em MIPS

Lara Teixeira Oliveira

você vai aprender

Como paralelizar um programa em linguagem de montagem do processador MIPS.
Como realizar chamadas de sistema operacional para a criação e gerenciamento de threads.

pré-requisitos

Conhecimento de programação básica em linguagem de montagem do processador MIPS.

hello world paralelo

Dado o seguinte código "hello world" em C#.

static void Main(string[] args)
{
  int i;

  for(i = 0; i < 2; i++)
    hello_func(i);
}

static void hello_func(int j)
{
  Console.WriteLine("Hello " + j + "\n");
}


Ele imprime a string "hello" duas vezes com o valor de sua respectiva iteração. Para paralelizar esse código, vamos dividir as iterações do laço de repetição entre duas threads, que serão executadas em paralelo.

Imagem 1 Imagem widget

chamadas de sistema

Para a paralelização do código apresentado, foram criadas três chamadas de sistema operacional para a criação e gerenciamento de threads: thread_fork, thread_id e num_thread.

thread_fork

A chamada thread_fork tem o código 161 e recebe como argumentos: o número de threads a serem criadas e a função que se deseja paralelizar.

thread_id

A chamada thread_id tem o código 162 e apenas retorna o identificador da thread em execução.

num_thread

A chamada num_thread tem o código 163 e retorna o número total de threads em execução.

Com estas três chamadas, é possível implementar o hello_world em paralelo.

programa sequencial

O programa "hello world" em linguagem de montagem é apresentado abaixo:

        .data

hello:  .asciiz "Hello\n"

        .text

main:         addi $s0, $zero, 0
for:          slti $t0, $s0, 2
              beq $t0, $zero, f_for
              jal hello_func
              addi $s0, $s0, 1
              j for
f_for         jr $ra

hello_func:   addi $v0, $zero, 4
              la $a0, hello
              syscall
              add $a0, $s0, $zero
              addi $v0, $zero, 1
              syscall
              jr $ra


fragmento de código widget
fragmento de código widget

paralelizando o hello world

Na versão paralela, cada thread executará a função hello_world em paralelo, imprimindo o seu identificador.

        .data

hello:  .asciiz "Hello\n"

        .text

main:         addi $v0, $zero, 161  // cria threads
              addi $a0, $zero, 2    // especifica que são duas threads
              la $a1, hello_func    // especifica a função
              syscall
              jr $ra

hello_func:   addi $v0, $zero, 4    // imprime string
              la $a0, hello        
              syscall
              addi $v0, $zero, 162  // lê o identificador da thread
              syscall
              add $a0, $v0, $zero   // imprime o identificador 
              addi $v0, $zero, 1
              syscall
              jr $ra

Como o laço de repetição possuía apenas duas iterações, elas são executadas em paralelo pelas duas threads criadas na chamada thread_fork. 

links úteis

Voltar