Многопоточная java-программа, не позволяющая процессору контролировать собственное тепло


Может ли программа java использовать все доступные потоки и мощность процессора до такой степени, что процессор больше не обнаруживает собственного тепла?

Я работал над небольшим проектом для целей обучения, когда я наткнулся на странное поведение, которое я не знал, что возможно через Java. Чтобы узнать немного о многопоточных, потокобезопасных и эффективных математических вычислениях, я сделал быструю и грязную программу для поиска простых чисел.

Проблемы начались, когда я установил размер пула потоков в 12 и использовал все потоки (6 core I7 hyperthreaded, спецификации будут ниже), что я обнаружил, мой процессор не реагировал на свое собственное повышение температуры, только когда я снова остановил программу, она заметила и начала вращать вентиляторы.

Характеристики используемого оборудования:

    Процессор: (6 ядер, 12 потоков) I7-5820k на частоте 3,3 ГГц
  • материнская плата: Asus X99-DELUX
  • процессор-вентилятор: NZXT Kreaken x61

Используемое измерительное программное обеспечение:

  • КАМЕРА NZXT
  • CPUZ

Некоторые тесты я провел, чтобы попытаться понять, что и почему это так.: Ofc мне нужно было установить, что это действительно происходит, поэтому я открыл оба process manager, CPU-Z и CAM, чтобы контролировать использование процессора и тепло, и, конечно же, когда я запустил код, все просто замерзло и осталось на тех же значениях (примерно около 35 C), но как только я остановил его, температура взлетела почти до 70C.
Выполнение того же теста всего с 10 нитями, оставляя 2 протектора нетронутые, вентиляторы постепенно увеличивались вместе с температурой.

Вот 3 основных класса в этой программе:

Потокобезопасный длинный публичный класс SyncedLong { рядовой Лонг вал;

    public SyncedLong(long val){
        this.val = val;
    }

    public synchronized void increment(){
        val++;
    }

    public synchronized long incrementAndGet(){
        val++;
        return val;
    }

    public synchronized long get(){
        return val;
    }
}

Мой класс ThreadControler для хранения и обработки активных потоков:

public class ThreadControler {

    ArrayList<PrimeCalculatorThread> primePool = new ArrayList<>();
    ExecutorService executor = Executors.newFixedThreadPool(10);

    public void increment() {
        if(executor.isTerminated()){executor = Executors.newFixedThreadPool(12);} //12 is the amount of threads on my cpu
        PrimeCalculatorThread pct = new PrimeCalculatorThread();
        primePool.add(pct);
        executor.execute(pct);

    }

    public void decrement() {
        PrimeCalculatorThread pct = primePool.get(primePool.size()-1);
        pct.terminate();
        primePool.remove(pct);
    }

    public void terminate() {
        for(PrimeCalculatorThread pct : primePool){
            pct.terminate();
        }
        primePool.clear();
        executor.shutdown();
    }
}

Наконец, номер cruncher, PrimeCalculatorThread

public class PrimeCalculatorThread implements Runnable {
    // 77263
    public static SyncedLong threaddedLong = new SyncedLong(0); //Startes a new SyncedLong at starting number 0.
    long currentNumber = 0;
    long lastNumber = 0;
    long a = 0;
    long b = 0;
    long c = 0;
    long startingNumber = 0;
    boolean foundPrime;
    boolean running = true;

    @Override
    public void run() {
        while (running) {
            currentNumber = threaddedLong.incrementAndGet();
            foundPrime = true;

            if (currentNumber % 2 != 0) {
                a = 0;
                while (a <= currentNumber) {
                    b = a;
                    while (b <= currentNumber) {
                        c = a * b;
                        if (a != currentNumber && b != currentNumber) {
                            if (c == currentNumber) {
                                foundPrime = false;

                            }
                        }
                        b++;
                    }
                    a++;
                }
                if (foundPrime) {
                    Output.println("Found prime: " + currentNumber + "    Difference: " + (currentNumber - lastNumber) + "    " + Thread.currentThread().getName());
                    lastNumber = currentNumber;
                }
            }
        }
    }

    public void terminate() {
        running = false;
    }
}

Использование Процессора использование процессора


Английский не является моим родным языком, поэтому не судите мою формулировку и грамматики слишком резко, пожалуйста, просто бросьте быстрый вопрос, если вы чувствуете, что что-то сформулировано неправильно или если это просто не имеет достаточного смысла(если таковой имеется).
1 3

1 ответ:

Современная технология intel настолько продвинута . Даже если вы думаете, что используете все ядра и потоки одновременно, на аппаратном уровне ОС выделяет и совместно использует процессор. Теперь просто чтобы доказать мой факт попробуйте воспроизвести видео в фоновом режиме во время работы этой программы, она должна работать( это может быть не гладко) .

Внутри процессора есть технология, которая предохраняет процессор от ожога из-за перегрева. Сначала он ускорит вентилятор, а затем, в конечном счете, его будет выключение системы температура продолжает расти .

Да, вы отчасти правы, вентилятор и cpuz требуют некоторого времени, чтобы отреагировать. Но если температура пересечет точку, процессор вызовет прерывание и потянет все действия..