• Как учить C / C++ на Linux?

    Ckpyt
    @Ckpyt
    Adamos, Зависит от задачи. У нас задача была кросс-платформенный клиент. Так как клиент изначально был на винде, то и вопросов не возникало.
    Ну и кроме того, VS - просто удобно. Не нашел iDE со схожим функционалом на Линуксе. Подскажите - буду рад.
  • Как учить C / C++ на Linux?

    Ckpyt
    @Ckpyt
    Adamos,
    Вообще-то главное достоинство изучения С++ под Линуксом - именно в отсутствии под ним Visual Studio и WinAPI.

    Не обманываейте. Visual Studio-проекты можно запускать и дебажить из-под студии на удаленном линуксе :-)
  • Почему на 4-х ядерном процессоре происходит эмуляция 12-и ядерного?

    Ckpyt
    @Ckpyt Автор вопроса
    1. Как ни странно, с атомиком получается медленнее.
    3. УУУПС! Забыл. Спасибо. Добавил в основной цикл sleep_for(1ms).
    4. Это чтобы оптимизатор не выкидывал код. Без оптимизатора результат после каждого построения был разный.
    5. Это решается увеличением количества прогонов. При сотне прогонов результат более гладкий

    Кстати, теперь да, убедился, что процессор 4-х ядерный.
    Спасибо!
  • Почему на 4-х ядерном процессоре происходит эмуляция 12-и ядерного?

    Ckpyt
    @Ckpyt Автор вопроса
    Толстый Лорри: Ну гипертрединг-то включен... так что, эмуляция 4-х ядерного поведения... И все равно, это не ответ на вопрос почему именно 12 потоков. Проверенно не на одном запуске.
  • Почему сопроцессор в тысячу раз медленнее процессора?

    Ckpyt
    @Ckpyt Автор вопроса
    Спасибо! Там было две ошибки: переполнение стэка и загрузка int командой fld Обе существенно замедляли время выполнения.
    Сейчас наконец-то все ок.
    threads: 1time block1:54, block2:40, tics per second:1000
    threads: 2time block1:66, block2:60, tics per second:1000
    threads: 3time block1:83, block2:62, tics per second:1000
    threads: 4time block1:108, block2:71, tics per second:1000
    threads: 5time block1:140, block2:116, tics per second:1000
    threads: 6time block1:145, block2:142, tics per second:1000
    threads: 7time block1:210, block2:158, tics per second:1000
    threads: 8time block1:230, block2:173, tics per second:1000

    П.с. не подскажите, почему сопроцессор должен быть в полтора-два раза медленнее процессора?
  • Почему сопроцессор в тысячу раз медленнее процессора?

    Ckpyt
    @Ckpyt Автор вопроса
    UPD: нашли первый баг, проблема не исчезла.

    #include "stdafx.h"
    #include <conio.h>
    #include <ctime>
    #include <thread>
    
    #define MAX_I 4000000
    
    unsigned __int32 rezult[64];
    
    std::thread* thr[8];
    
    void StartPR(int str)
    {
    	int i = MAX_I;
    	int x = str;
    	__asm {
    		    mov eax, MAX_I
    			xor ebx, ebx
    			xor ecx, ecx
    			xor edx, edx
    circle:
    			dec eax
    			mov i, eax
    			add ebx, i
    			add ecx, i
    			add edx, i
    
    			cmp eax, 0
    			jnz circle
    
    		mov eax, x
    		mov esi, eax
    
    		mov [rezult + esi], eax
    		add esi, 4
    		mov [rezult + esi], ebx
    		add esi, 4
    		mov [rezult + esi], ecx
    		add esi, 4
    		mov [rezult + esi], edx
    	}
    }
    
    void StartMMX(int str)
    {
    	int i = MAX_I;
    	int x = str;
    	_asm {
    
    		mov eax, MAX_I
    		//fldz
    		xor ebx, ebx
    		//fldz
    		xor ecx, ecx
    			
    circle2:
    
    			dec eax
    			mov i, eax
    			add ecx, i
    			add ebx, i
    
    			//fincstp
    			//fld i
    			//fadd st(1), st(0)
    			//fadd st(2), st(0)
    
    			cmp eax, 0
    			jnz circle2
    
    		mov eax, x
    		mov esi, eax
    		mov dword ptr[rezult + esi], ebx
    		add esi, 4
    		//fstp [rezult + esi]
    		add esi, 4
    		mov dword ptr[rezult + esi], ecx
    		add esi, 4
    		//fstp [rezult + esi]
    	}
    }
    
    void stardThreads(int numOfThread)
    {
    	printf("threads: %i", numOfThread);
    	int i = 0;
    	clock_t strt = clock();
    	for (int i = 1; i < numOfThread; i++)
    	{
    		thr[i] = new std::thread(StartPR, i * 32);
    	}
    	StartPR(0);
    
    	clock_t strt2 = clock();
    	clock_t bk1 = strt2 - strt;
    
    	i = 16;
    	for (int i = 1; i < numOfThread; i++)
    	{
    		thr[i] = new std::thread(StartMMX, i * 32 + 16);
    	}
    	StartMMX(i);
    	clock_t bk2 = clock() - strt2;
    	printf("time block1:%i, block2:%i, tics per second:%i\n", (__int32)bk1, (__int32)bk2, CLOCKS_PER_SEC);
    	//for (int i = 0; i < numOfThread * 8; i++)
    		//printf("rezult[%i] = %u \n", i, rezult[i]);
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	for (int i = 1; i < 9; i++)
    		stardThreads(i);
    
    	_getch();
    	return 0;
    }


    результат
    threads: 1time block1:12, block2:6048, tics per second:1000
    threads: 2time block1:16, block2:5641, tics per second:1000
    threads: 3time block1:10, block2:3066, tics per second:1000
    threads: 4time block1:9, block2:2406, tics per second:1000
    threads: 5time block1:11, block2:2694, tics per second:1000
    threads: 6time block1:10, block2:3201, tics per second:1000
    threads: 7time block1:13, block2:3292, tics per second:1000
    threads: 8time block1:16, block2:5270, tics per second:1000

    Убираем команды сопроцессора, тайминги внезапно начинают совпадать.
  • Почему сопроцессор в тысячу раз медленнее процессора?

    Ckpyt
    @Ckpyt Автор вопроса
    jcmvbkbc
    Окей, этот баг я исправил. Получил странные результаты.
    clock_t strt2 = clock();
    	clock_t bk1 = strt2 - strt;
    ...
    	clock_t bk2 = clock() - strt2;


    результат:
    threads: 1time block1:12, block2:6042, tics per second:1000
    threads: 2time block1:16, block2:5476, tics per second:1000
    threads: 3time block1:10, block2:3208, tics per second:1000
    threads: 4time block1:12, block2:2463, tics per second:1000
    threads: 5time block1:11, block2:2887, tics per second:1000
    threads: 6time block1:34, block2:3543, tics per second:1000
    threads: 7time block1:12, block2:4317, tics per second:1000
    threads: 8time block1:28, block2:4598, tics per second:1000

    Почему он такой странный? Если полностью убираю обращение к сопроцу - время block1 = block2.
    Почему работа с сопроцом занимает от 2 до 6 секунд? Откуда это?
    П.с. на ноуте включен гипертрейдинг
  • Почему сопроцессор в тысячу раз медленнее процессора?

    Ckpyt
    @Ckpyt Автор вопроса
    nirvimel:
    #include "stdafx.h"
    #include <conio.h>
    #include <ctime>
    #include <thread>
    
    #define MAX_I 4000000
    
    unsigned __int32 rezult[64];
    
    std::thread* thr[8];
    
    void StartPR(int str)
    {
    	int i = MAX_I;
    	int x = str;
    	__asm {
    		    mov eax, MAX_I
    			xor ebx, ebx
    			xor ecx, ecx
    			xor edx, edx
    circle:
    			dec eax
    			mov i, eax
    			add ebx, i
    			add ecx, i
    			add edx, i
    
    			cmp eax, 0
    			jnz circle
    
    		mov eax, x
    		mov esi, eax
    
    		mov [rezult + esi], eax
    		add esi, 4
    		mov [rezult + esi], ebx
    		add esi, 4
    		mov [rezult + esi], ecx
    		add esi, 4
    		mov [rezult + esi], edx
    	}
    }
    
    void StartMMX(int str)
    {
    	int i = MAX_I;
    	int x = str;
    	_asm {
    
    		mov eax, MAX_I
    		fldz
    		xor ebx, ebx
    		fldz
    		xor ecx, ecx
    			
    circle2:
    
    			dec eax
    			mov i, eax
    			add ecx, i
    			add ebx, i
    
    			fincstp
    			fld i
    			fadd st(1), st(0)
    			fadd st(2), st(0)
    
    			cmp eax, 0
    			jnz circle2
    
    		mov eax, x
    		mov esi, eax
    		mov dword ptr[rezult + esi], ebx
    		add esi, 4
    		fstp [rezult + esi]
    		add esi, 4
    		mov dword ptr[rezult + esi], ecx
    		add esi, 4
    		fstp [rezult + esi]
    	}
    }
    
    void stardThreads(int numOfThread)
    {
    	printf("threads: %i", numOfThread);
    	int i = 0;
    	clock_t strt = clock();
    	for (int i = 1; i < numOfThread; i++)
    	{
    		thr[i] = new std::thread(StartPR, i * 32);
    	}
    	StartPR(0);
    	clock_t bk1 = clock() - strt;
    	i = 16;
    	for (int i = 1; i < numOfThread; i++)
    	{
    		thr[i] = new std::thread(StartMMX, i * 32 + 16);
    	}
    	StartMMX(i);
    	clock_t bk2 = clock() - bk1;
    	printf("time block1:%i, block2:%i, tics per second:%i\n", (__int32)bk1, (__int32)bk2, CLOCKS_PER_SEC);
    	//for (int i = 0; i < numOfThread * 8; i++)
    		//printf("rezult[%i] = %u \n", i, rezult[i]);
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	for (int i = 1; i < 9; i++)
    		stardThreads(i);
    
    	_getch();
    	return 0;
    }


    вывод:
    threads: 1time block1:13, block2:5659, tics per second:1000
    threads: 2time block1:12, block2:11975, tics per second:1000
    threads: 3time block1:17, block2:15983, tics per second:1000
    threads: 4time block1:9, block2:18935, tics per second:1000
    threads: 5time block1:27, block2:21661, tics per second:1000
    threads: 6time block1:30, block2:25007, tics per second:1000
    threads: 7time block1:19, block2:28853, tics per second:1000
    threads: 8time block1:21, block2:33343, tics per second:1000

    очень смущает, что время работы сопроцессора линейно растет с количеством потоков.
    Учитывая, что у ноута два ядра с гипертрейдингом.
    Процессор core i5-5200U
  • Как расшифровать RSA, не имея открытого ключа?

    Ckpyt
    @Ckpyt Автор вопроса
    evnuh: Сорри, время два с небольшим... *файл лицензии, не ключ. Ключ в экзешнике.
  • Как расшифровать RSA, не имея открытого ключа?

    Ckpyt
    @Ckpyt Автор вопроса
    evnuh: затем, чтобы предотвратить ШИФРОВАНИЕ. Вот у вас есть ключ лицензии, у него есть какие-то данные. Отсутствие публичного ключа как раз и мешает на месте создать свой, новый, уникальный ключ лицензии. А так как подложить свой закрытый ключ тоже весьма нетривиальная задача, то, в общем и целом, задача лицензирования решена.
  • Как расшифровать RSA, не имея открытого ключа?

    Ckpyt
    @Ckpyt Автор вопроса
    У вас не правильный комментарий. Он должен отвечать на вопрос, а не изменять начальные условия :-)
  • Как расшифровать RSA, не имея открытого ключа?

    Ckpyt
    @Ckpyt Автор вопроса
    Denis Zagayevskiy: Для этого ему придется залезть в код программы, потом подписать ее той же подписью, что была и до этого...
    Короче, на этот счет можно не париться.
  • Как расшифровать RSA, не имея открытого ключа?

    Ckpyt
    @Ckpyt Автор вопроса
    1) Да, я по открытому каналу передаю шифротекст и закрытый ключ. Таким образом, никто не может моим открытым ключом записать новые данные, в то время как закрытый ключ подменить достаточно сложно.
    Задача - лицензирование. Достаточно типовая, если глянуть в реестр решарпера.
    2) Увы, я это осознал. Поэтому, попробовал поменять местами открытую и секретную экспоненты. В теории, зашифровав сперва секретной, а потом открытой экспонентой, я должен был бы получить расшифрованный текст. Увы, Майкрософт и здесь меня обломал: на секретную экспоненту в каестве открытой говорит, что плохие данные.
  • Аналогия switch

    Ckpyt
    @Ckpyt Автор вопроса
    Спасибо! Работает! Я не представлял, что typedef'ом можно так обманывать компилятор :-)
    У меня на руках сервер. Там много высокоуровневого кода, включая итераторы и аллокаторы, но много и низкоуровневого. Включая ассемблерные вставки.
    Сервер достался по наследству, я его изучаю и правлю.
    Так что, мне сложно отличить С++ код от кода С.
  • Аналогия switch

    Ckpyt
    @Ckpyt Автор вопроса
    Ан нет. Не получается.
    Пишет —
    void* t[256](); — массив функций не разрешен.
    либо, если
    void* t[256];
    1>Hello.cpp(94): error: expression preceding parentheses of apparent call must have (pointer-to-) function type
    1> t[i]? t[i](): t[i];
    1> ^
  • Аналогия switch

    Ckpyt
    @Ckpyt Автор вопроса
    Спасибо.
    Сейчас вылизываю код с точки зрения синтаксиса.
  • Аналогия switch

    Ckpyt
    @Ckpyt Автор вопроса
    Т.е. видим последовательный перебор значений, скорость — O(N).
    мой код — O(1).
  • Аналогия switch

    Ckpyt
    @Ckpyt Автор вопроса
    тест:
    switch(i){
    	case 1:
    		i++;
    		break;
    	case 2:
    		i+=2;
    		break;
    	case 3:
    		i+=3;
    		break;
    	default:
    		i+=4;
    	}
    


    компилируется в
    004010AE: 8B4DFC               mov ecx, [ebp-04]
    004010B1: 8BC1                 mov eax, ecx
    *switch
    004010B3: 48                   dec eax
    004010B4: 7419                 je  004010CF
    004010B6: 48                   dec eax
    004010B7: 740F                 je  004010C8
    004010B9: 48                   dec eax
    004010BA: 7405                 je  004010C1
    004010BC: 83C104               add ecx, 00000004
    004010BF: EB13                 jmp 004010D4
    *end switch
    * Jump:
     004010BA(C) 
    
    004010C1: B906000000           mov ecx, 00000006
    004010C6: EB0C                 jmp 004010D4
    
    * Jump:
     004010B7(C) 
    
    004010C8: B904000000           mov ecx, 00000004
    004010CD: EB05                 jmp 004010D4
    
    * Jump:
     004010B4(C) 
    
    004010CF: B902000000           mov ecx, 00000002
    
    * Jump:
     004010BF(U), 004010C6(U), 004010CD(U) 
    
    004010D4: 51                   push ecx
    
  • Аналогия switch

    Ckpyt
    @Ckpyt Автор вопроса
    2, да, конечно. Просто это тестовый пример, сделанный мной просто для проверки идеи :-)

    1 — Хотелось бы всего и сразу. :-) Но в первую очередь, конечно, быстродействие.