计算一个数组所有元素之和(基于多处理器的并行开发讨论)

来源:互联网 发布:js radio取消选中事件 编辑:程序博客网 时间:2024/04/28 14:27

我早些时候上传了 《双核协作完成搜索β》(详细可见我的资源),这个方法是无锁并行计算方法,下面介绍一种更长见的带锁的多处理器计算方法。这个方法若使用像OpenMP这样的编译工具的话会使得代码更好看,更自然一些。

    以下代码是我基于Blackfin561双核DSP,VisualDSP++4.5环境下通过测试的。这个方法比无锁更容易实现,不过如果没有OpenMP的话,在对一些临界变量进行上锁时必须十分小心,加锁后务必不能忘了解锁。

 

// 在共享存储区中源文件中
// shared.c

#include <stdio.h>
#include "core_intr/core_sync.h"
 
#pragma file_attr("sharing=MustShare")
 
static volatile int array[100];
 
static volatile int callA = 0, callB = 0;

static volatile int sum = 0;

void InitArray(void)
{
     int i;
 
     for(i=0; i<100; i++)
         array[i] = i + 1;
}

void InvokeCoreB(void)
{
     callB = 1;
 
     while(callA != 1);
}

void InvokeCoreA(void)
{
     callA = 1;
 
     while(callB != 1);
}

void CalculateArray0(void)
{
    register int i;
 
    for(i=0; i<100; i++)
         sum += array[i];
}

void CalculateArray1(void)
{
     static volatile int loopIndex = 0;
     static volatile LOCK_TYPE lockForIndex = 0, lockForResult = 0;
     register int tempIndex;
 
    for(;;)
    {
        spin_try_getlock(&lockForIndex);
        if(loopIndex >= 100)
        {
            spin_release_lock(&lockForIndex);
            return;
        }
        tempIndex = loopIndex++;
        spin_release_lock(&lockForIndex);
  
        spin_try_getlock(&lockForResult);
        sum += array[tempIndex];
        spin_release_lock(&lockForResult);
     }
}

void OutputResult(void)
{
     printf("The answer is: %d/n", sum); 
}

 

// 在核A中main.cpp
#include "./core_intr/intr.h"
 
EXTERN void InitArray(void);
EXTERN void CalculateArray1(void);
EXTERN void OutputResult(void);
EXTERN void CalculateArray0(void);
EXTERN void InvokeCoreB(void);

int main(void)
{
    SICA_SYSCR &= ~0x20;    // 唤醒并激活核B
 
    InitArray();
 
    ssync();
 
    InvokeCoreB();
 
    CalculateArray1();
 
    OutputResult();
    return 0;
}


 

 

// 在核B的main.cpp中

EXTERN void CalculateArray1(void);
EXTERN void InvokeCoreA(void);

int main(void)
{
    InvokeCoreA();
 
    CalculateArray1();
 
    return 0;
}

 

 

下面再附上旋锁的实现方法:

  1. #ifndef SHARED_CORE_SYNC_H
  2. #define SHARED_CORE_SYNC_H
  3. #include "../../common/common.h"
  4. typedef uint32  LOCK_TYPE;
  5. EXTERN void core_delay(uint32 cycles);
  6. EXTERN BOOL core_lockEx(volatile LOCK_TYPE* pSpring);
  7. EXTERN void core_release_lockEx(volatile LOCK_TYPE* pSpring);
  8. _INLINE_ BOOL lock_try_get(volatile LOCK_TYPE* pSpring)
  9. {
  10.     BOOL result;
  11.     
  12.     asm("testset(%1);"
  13.         "%0 = cc;" : 
  14.         "=d"(result):
  15.         "a"(pSpring)
  16.         );
  17.         
  18.     return result;
  19. }
  20. _INLINE_ void spin_try_getlock(volatile LOCK_TYPE* pSpring)
  21. {
  22.     while(!lock_try_get(pSpring));
  23. }
  24. _INLINE_ void spin_release_lock(volatile LOCK_TYPE* pSpring)
  25. {
  26.     *pSpring = 0;
  27. }
  28. #endif

 

原创粉丝点击