gpt4 book ai didi

java - 影响多线程操作系统的核心数量

转载 作者:行者123 更新时间:2023-12-01 13:15:54 25 4
gpt4 key购买 nike

我正在尝试确定有关我的电脑工作方式的信息,我有一台双核电脑,我正在尝试用我编写的代码来测试它,当每个线程处理时,程序使用线程(在java中)将两个矩阵相乘矩阵行数除以线程数。因此,在两个 1024 X 1024 矩阵上测试我的代码,我得到了这个结果 - (所有结果都是 10 次运行的中位数)1 个线程 - 9.878 秒\\\2 个线程 - 5.944 秒\\\3 个线程 - 5.062 秒\\\4 个线程 - 4.895 秒\\\5 到 1024 个线程,时间在 4.8 到 5.3 秒之间变化\\\.

我想弄清楚为什么前 4 个线程的时间下降幅度较小?难道工作不应该在核心之间平均分配吗?这样 1 个线程 10 秒,2 个线程 5 秒,其余的只需要更长的时间,因为我只有 2 个核心,添加更多线程只是创建更多上下文切换。

我无法理解的第二件事,假设在第四个线程之后,我的电脑只是在线程之间切换,这并没有真正分割工作,而只是切换哪个线程执行某项工作,那么时间不应该急剧增加吗1024个线程只是因为我让它做很多上下文切换?

预先感谢您对此事的任何回复

添加代码 -

    /**
* A class representing matrix multiplying threads , implements runnable
* used to test the time difference according to changes in amount of
* threads used in the program !
*
* @author R.G
*/
public class MatrixMultThread implements Runnable{

//Thread fields and constants
private static final String INT_ERROR = "An error has occured during thread join";
private static final String THREAD_COUNT_ERROR = "Invalid number of threads";
static final int MATRIX_ROW = 1024;
static final int MATRIX_COL = 1024;
static final int UPPER_THREAD_LIMIT = MATRIX_ROW;
private int startRow;
private int endRow;
private float[][] target;
private float[][] sourceTwo;
private float[][] sourceOne;

/**
* MatrixMultThread constructor - constructs the threads that handle multiplication.
*
* @param startRow - the row this thread should start calculating from
* @param endRow - the row this thread should stop calculating at (included in calc)
* @param sourceOne - first matrix in the multiplication
* @param sourceTwo - second matrix in the multiplication
* @param target - result matrix
*/
public MatrixMultThread(int startRow, int endRow, float[][] sourceOne, float[][] sourceTwo, float[][] target){
this.startRow = startRow;
this.endRow = endRow;
this.target = target;
this.sourceOne = sourceOne;
this.sourceTwo = sourceTwo;

}

/**
* Thread run method, invoking the actual calculation regarding
* this thread's rows.
*/
public void run() {
int sum = 0;
for(; startRow <= endRow; startRow++){
for(int j = 0; j < MATRIX_COL ; j++){
for(int i = 0; i < MATRIX_ROW ; i++){
sum += sourceOne[startRow][i] * sourceTwo[i][j];
}
target[startRow][j] = sum;
sum = 0;
}
}
}

/**
* A method used for multiplying two matrices by threads.
*
* @param a - first source matrix
* @param b - second source matrix
* @param threadCount - number of threads to use in the multiplication
*/
public static float[][] mult(float[][] a, float[][]b, int threadCount) {
if(threadCount > UPPER_THREAD_LIMIT || threadCount < 1){
System.out.println(THREAD_COUNT_ERROR);
System.exit(1);
}

//Result matrix
float[][] result = new float[MATRIX_ROW][MATRIX_COL];
Thread[] threadList = new Thread[threadCount];

//Creating the threads
int firstRow = 0;
int lastRow = 0;
for (int i = 0; i < threadCount ; i++){
firstRow = i * (MATRIX_ROW / threadCount);
lastRow = ((i + 1) * (MATRIX_ROW / threadCount)) -1 ;
Thread singleThread;

//in case the number does not divide exactly we let the last thread do a bit extra work
//to compensate on the missing few matrix lines.
if((i + 1) == threadCount){
singleThread = new Thread(new MatrixMultThread(firstRow, MATRIX_ROW - 1, a, b, result));
}else{
singleThread = new Thread(new MatrixMultThread(firstRow, lastRow, a, b, result));
}
threadList[i] = singleThread;
singleThread.start();
}

//Join loop
for (int i = 0; i < threadCount ; i++){
try {
threadList[i].join();
} catch (InterruptedException e) {
System.out.println(INT_ERROR);
System.exit(1);
}
}
return result;
}


/**
* Main method of multiplying two matrices using various number of threads
* functionality time is being tested.
*
* @param args.
*/
public static void main(String[] args) {

//Thread number and timers for milliseconds calculation.
int numberOfThreads = 1024;
long startTimer, endTimer;

//Initializing matrices
float[][] a = new float[MATRIX_ROW][MATRIX_COL];
float[][] b = new float[MATRIX_ROW][MATRIX_COL];

for(int i = 0 ; i < MATRIX_ROW ; i++){
for(int j = 0 ; j < MATRIX_COL ; j++){
a[i][j] = (float)(Math.random() * ((100 - 0) + 1)); //Random matrices (values
b[i][j] = (float)(Math.random() * ((100 - 0) + 1)); //between 0 and 100).
}
}

//Timing the multiplication.
startTimer = System.currentTimeMillis();
mult(a, b, numberOfThreads);
endTimer = System.currentTimeMillis();
System.out.println("Matrices multiplied in " + (endTimer - startTimer) + " miliseconds");
}
}

最佳答案

您的程序受 CPU 限制。这意味着它消耗了整个调度程序量子。所以上下文切换开销相对较小:

overhead = ((consumed_quanta + context_switch_time) / consumed_quanta) - 1

在自愿离开 CPU 的进程中,上下文切换开销会更大:例如两个线程不断地在它们之间传递相同的消息(因此一个线程发送消息,而另一个线程读取消息,然后第二个线程将消息发送给第一个线程,依此类推)将产生非常高的上下文切换开销。

SMT(x86 领域的超线程)允许单个核心服务多个线程,就好像它是多个逻辑核心一样。由于 CPU 通常必须等待外部资源(例如:它需要来自缓存的数据),因此允许另一个线程在这些死区期间继续运行可以通过相对较少的额外电路来提高性能(与添加另一个核心相比)。由于 HT 在实际系统中(不是在综合基准测试中)性能改进的典型引用数字约为 10-20%,但是 YMMV:HT 可能会在某些边缘情况下使性能变得更差,并且在不同的边缘情况下可能会带来更显着的改进-案例。

关于java - 影响多线程操作系统的核心数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22476221/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com