Linux下使用POSIX Thread作多核多线程并行计算

文章讨论了在Linux系统中使用POSIX线程库创建线程时,线程可能会被调度到不同处理器核心上执行的情况。强调了开发者不能假设线程的执行位置,并推荐在多核环境下使用GrandCentralDispatch机制。示例代码展示了如何创建线程并进行简单的计算任务,同时提到了使用`rdtsc`指令获取CPU周期数来评估性能。

POSIX线程库根据处理器、操作系统等特性封装了一台线程处理的接口。对于目前基于x86处理器架构的Linux系统来说,它往往会默认地将新创建的一个线程调度到与主线程不同的核中执行,如果这样能更好地平衡负荷的话。因此,在使用POSIX线程时,开发者不能断言当前创建的线程是否运行在与主线程相同的核心下,也不能断言一定运行在与主线程不同的核心下。当然,由于POSIX线程具有时间片轮询调度(Round-Robin),因此即便与主线程处于一个核心,使用旋锁的话,性能影响也不会太大。不过多核多线程其实最好还是使用类似于macOS以及iOS中的Grand Central Dispatch机制,显式给出线程的调度队列。

在Linux下使用POSIX线程时应当先得加上 libpthread.so 动态库,因此在连接器选项中加上 -lpthread

以下代码在联想Z475,AMD APU A6-3420M,4GB DDR3,Ubuntu12.04系统下完成测试。

C代码:

/*
 ============================================================================
 Name        : ThreadTest.c
 Author      : Zenny Chen
 Version     :
 Copyright   : Your copyright notice
 
 Description : Hello World in C, Ansi-style
 ============================================================================
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
 
#define TOTAL_CALC_ITEMS    1000000
 
extern unsigned long getRealtimeCycles(void);
 
static volatile _Bool isFinished = 0;
static volatile int sum4Core2 = 0;
 
static void* threadProc(void *param)
{
    int sum = 0;
    int *pSrc = (int*)param;
    for(int i = TOTAL_CALC_ITEMS / 2; i < TOTAL_CALC_ITEMS; i++)
        sum += pSrc[i];
 
    sum4Core2 = sum;
    isFinished = 1;
 
    return NULL;
}
 
static int sourceArray[TOTAL_CALC_ITEMS];
 
static void testOpt(void)
{
    // Initialize the array
    for(int i = 0; i < TOTAL_CALC_ITEMS; i++)
        sourceArray[i] = i + 1;
 
    pthread_t threadHandle;
 
    pthread_attr_t attr;
    if(pthread_attr_init(&attr) != 0)
    {
        puts("Attribute failed to create!");
        return;
    }
    pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
 
    if(pthread_create(&threadHandle, &attr, &threadProc, sourceArray) != 0)
    {
        puts("Thread failed to create!");
        return;
    }
    int polacy = -1;
    pthread_attr_getschedpolicy(&attr, &polacy);
    printf("Current sched polacy is: %d\n", polacy);
 
    int sum = 0;
    unsigned long ticks = getRealtimeCycles();
 
    for(int i = 0; i < TOTAL_CALC_ITEMS / 2; i++)
        sum += sourceArray[i];
 
    while(!isFinished)
        __asm__("pause");
    sum += sum4Core2;
 
    ticks = getRealtimeCycles() - ticks;
 
    printf("The number of cycles is: %lu\n", ticks);
    printf("The sum is: %d\n", sum);
 
    pthread_attr_destroy(&attr);
}
 
static void testNaive(void)
{
    // Initialize the array
    for(int i = 0; i < TOTAL_CALC_ITEMS; i++)
        sourceArray[i] = i + 1;
 
    int sum = 0;
    unsigned long ticks = getRealtimeCycles();
 
    for(int i = 0; i < TOTAL_CALC_ITEMS; i++)
        sum += sourceArray[i];
 
    ticks = getRealtimeCycles() - ticks;
 
    printf("The number of cycles is: %lu\n", ticks);
    printf("The sum is: %d\n", sum);
}
 
int main(void)
{
    testOpt();
    testNaive();
    testOpt();
    testNaive();
 
    return EXIT_SUCCESS;    // 1784293664
}

汇编代码:

.text
.align 4
.globl getRealtimeCycles

getRealtimeCycles:

    rdtsc
    shl     $32, %rdx
    or      %rdx, %rax
    ret

大家可以尝试编译运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值