我早些时候上传了 《双核协作完成搜索β》(详细可见我的资源),这个方法是无锁并行计算方法,下面介绍一种更长见的带锁的多处理器计算方法。这个方法若使用像OpenMP这样的编译工具的话会使得代码更好看,更自然一些。
以下代码是我基于Blackfin561双核DSP,VisualDSP++4.5环境下通过测试的。这个方法比无锁更容易实现,不过如果没有OpenMP的话,在对一些临界变量进行上锁时必须十分小心,加锁后务必不能忘了解锁。
//
在共享存储区中源文件中
// shared.c
#include <stdio.h>
#include "core_intr/core_sync.h"
// 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);
}
}
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);
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);
EXTERN void CalculateArray1(void);
EXTERN void InvokeCoreA(void);
int main(void)
{
InvokeCoreA();
CalculateArray1();
return 0;
}
下面再附上旋锁的实现方法:
- #ifndef SHARED_CORE_SYNC_H
- #define SHARED_CORE_SYNC_H
- #include "../../common/common.h"
- typedef uint32 LOCK_TYPE;
- EXTERN void core_delay(uint32 cycles);
- EXTERN BOOL core_lockEx(volatile LOCK_TYPE* pSpring);
- EXTERN void core_release_lockEx(volatile LOCK_TYPE* pSpring);
- _INLINE_ BOOL lock_try_get(volatile LOCK_TYPE* pSpring)
- {
- BOOL result;
- asm("testset(%1);"
- "%0 = cc;" :
- "=d"(result):
- "a"(pSpring)
- );
- return result;
- }
- _INLINE_ void spin_try_getlock(volatile LOCK_TYPE* pSpring)
- {
- while(!lock_try_get(pSpring));
- }
- _INLINE_ void spin_release_lock(volatile LOCK_TYPE* pSpring)
- {
- *pSpring = 0;
- }
- #endif