一、多核心运行程序
在linux下我们可以指定线程或者进程运行在指定的cpu核心上,操作方法如下:
1)运行进程指定cpu核心
taskset -c 2 ./app //-c指定运行的cpu核心号,从0计数,查看效果如下:

2)运行线程指定cpu核心
主要是设置线程的属性,具体代码如下,详看main函数。
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <pthread.h>
#include <time.h>
void* thread_func0(void* arg) {
    int iterations = 1000000000; // 迭代次数
    double a = 3.14159; // 乘法操作的乘数
    double b = 2.71828; // 乘法操作的被乘数
    double sum = 0.0; // 加法操作的累加器
	struct timespec start, end;
    clock_gettime(CLOCK_MONOTONIC, &start);
    // 执行乘法运算
    for (int i = 0; i < iterations; ++i) {
        double c = a * b;
        sum += c; // 将乘法结果加到累加器上
    }
    clock_gettime(CLOCK_MONOTONIC, &end);
    double time_spent = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;
    printf("cpu0 Performed %d in %f seconds\n", iterations, time_spent);
    printf("cpu0 Resulting sum: %f\n", sum);
    return NULL;
}
void* thread_func1(void* arg) {
    int iterations = 1000000000; // 迭代次数
    double a = 3.14159; // 乘法操作的乘数
    double b = 2.71828; // 乘法操作的被乘数
    double sum = 0.0; // 加法操作的累加器
	struct timespec start, end;
    clock_gettime(CLOCK_MONOTONIC, &start);
    // 执行乘法运算
    for (int i = 0; i < iterations; ++i) {
        double c = a * b;
        sum += c; // 将乘法结果加到累加器上
    }
    clock_gettime(CLOCK_MONOTONIC, &end);
    double time_spent = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;
    printf("cpu1 Performed %d in %f seconds\n", iterations, time_spent);
    printf("cpu1 Resulting sum: %f\n", sum);
    return NULL;
}
int main() {
 	pthread_t thread0, thread1; // 为每个线程使用不同的变量
    pthread_attr_t attr0, attr1; // 为每个线程属性使用不同的变量
    unsigned long mask0 = 1UL << 2; // 将线程绑定到CPU核心2
	unsigned long mask1 = 1UL << 3; // 将线程绑定到CPU核心3
	// 初始化线程属性
    pthread_attr_init(&attr0);
    pthread_attr_init(&attr1);
    pthread_attr_setaffinity_np(&attr0, sizeof(mask0), &mask0);
    pthread_create(&thread0, &attr0, thread_func0, NULL);
    pthread_attr_setaffinity_np(&attr1, sizeof(mask1), &mask1);
    pthread_create(&thread1, &attr1, thread_func1, NULL);
    // 等待线程0和线程1完成
    pthread_join(thread0, NULL);
    pthread_join(thread1, NULL);
    return 0;
}编译后运行效果如下(代码指定了2和3,从0计数):

3)两者的优先级
代码中的线程属性设置cpu核心为2和3,进程以cpu核心0来运行,实际运行在核心2和3上。
测试代码用上述不变,运行命令为:taskset -c 0 ./app
因此,可得结论:在进程和线程都指定运行的cpu核心时,以线程为准。
二、多核心运行的时间测量需要注意的事项
1)多核计时异常
在测试运行时间时,遇到一个问题,最开始我使用的时间测试代码如下:
clock_t start = clock();//测量开始时间
//功能代码
//...
clock_t end = clock();// 测量结束时间
double time_spent = (double)(end - start) / CLOCKS_PER_SEC;这个代码在测试单核运行的代码时,时间是对的,但是使用多核运行时,发现这个代码统计的时间是我实际手机计时的2倍,怀疑是该函数统计了本程序对所有cpu的占用时间,即双核的时间。
后修改时间测量代码如下:
struct timespec start, end;
clock_gettime(CLOCK_MONOTONIC, &start);
//功能代码
//...
clock_gettime(CLOCK_MONOTONIC, &end);
double time_spent = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;测试时间和手机测试的一致。
2)clock() 和 clock_gettime() 比较
 
clock() 和 clock_gettime() 都是 C 语言标准库中用于获取时间的函数,但它们在用途和行为上有一些重要的区别:
-  定义和来源:- clock()函数定义在- <time.h>头文件中,它测量的是程序占用 CPU 的时间(也称为 CPU 时间或处理器时间)。它返回程序启动以来的时钟周期数,这个值是通过处理器的时钟周期来计算的。
- clock_gettime()函数是 POSIX.1-2001 标准的一部分,也定义在- <time.h>中,它提供了更精确的时间测量。它可以测量多种类型的时间,包括实时时间(系统时间)、进程时间、线程时间等。
 
-  时间类型:- clock()只能测量程序占用 CPU 的时间。
- clock_gettime()可以测量多种时间,通过指定不同的时钟 ID 来获取不同类型的时间。例如:- CLOCK_REALTIME:返回以系统实时时间为基础的时间,受系统时间的更改影响。
- CLOCK_MONOTONIC:返回一个单调时钟,它以系统启动为基础,不受系统时间更改的影响,适合测量时间间隔。
- CLOCK_PROCESS_CPUTIME_ID:返回调用进程占用的 CPU 时间总和。
- CLOCK_THREAD_CPUTIME_ID:返回调用线程占用的 CPU 时间。
 
 
-  精度:- clock()的精度受限于系统和硬件,通常以秒为单位,精度较低。
- clock_gettime()通常提供更高的精度,可以测量到纳秒级别。
 
-  返回值:- clock()返回一个- clock_t类型的值,表示程序占用 CPU 的时钟周期数。如果失败,返回- ((clock_t) -1)。
- clock_gettime()成功时返回 0,失败时返回 -1,并设置- errno以指示错误。
 
-  使用场景:- clock()适用于需要测量程序执行时间的场景,但它不适用于测量墙上时钟时间(实际时间)。
- clock_gettime()适用于需要高精度时间测量的场景,包括但不限于测量墙上时钟时间、系统时间、进程或线程的 CPU 时间。
 
-  多线程环境:- 在多线程环境中,clock()可能无法准确反映单个线程的 CPU 时间,因为它测量的是整个进程的 CPU 时间。
- clock_gettime()通过- CLOCK_THREAD_CPUTIME_ID可以准确测量单个线程的 CPU 时间。
 
- 在多线程环境中,
-  系统依赖性:- clock()是 C 语言标准的一部分,几乎所有的 C 语言环境都支持。
- clock_gettime()是 POSIX 标准的一部分,可能在非 POSIX 兼容的系统上不可用或需要特定的编译器标志。
 
总结来说,clock_gettime() 提供了更多的功能和更高的精度,是现代 C 语言编程中推荐的时间测量函数。而 clock() 由于其较低的精度和对多线程支持的限制,在现代编程中使用较少。
![C++map容器中operator[ ]的实现原理](https://i-blog.csdnimg.cn/direct/18e0925791b54b1d874646a9914fd428.png)


















