Добавлена многопоточность в патерны 0x00000000, 0xFFFFFFFF, 0xAAAAAAAA, 0x55555555 запускается многопточочный режим при -t(Чисто потоков)

This commit is contained in:
romenskiy 2025-06-20 14:51:45 +03:00
parent 988630f985
commit b10148056b
2 changed files with 168 additions and 32 deletions

155
main.c
View file

@ -6,63 +6,154 @@
#include <unistd.h> #include <unistd.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <errno.h> #include <errno.h>
#include <pthread.h>
#include <ctype.h>
#define DEBUG 0
#define jemalloc 0
#if defined(DEBUG) && DEBUG > 1
#define DEBUG_PRINT(fmt, args...) fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt, \
__FILE__, __LINE__, __func__, ##args)
#elif DEBUG == 1
#define DEBUG_PRINT(fmt, args...) fprintf(stderr, "DEBUG: %d:%s(): " fmt, \
__LINE__, __func__, ##args)
#else
#define DEBUG_PRINT(fmt, args...) /* Don't do anything in release builds */
#endif
#define BLOCK_SIZE (1024ULL*1024ULL*1024ULL*8) #define BLOCK_SIZE (1024ULL*1024ULL*1024ULL*8)
uint32_t test_patterns[] = {0x00000000, 0xFFFFFFFF, 0xAAAAAAAA, 0x55555555}; uint32_t test_patterns[] = {0x00000000, 0xFFFFFFFF, 0xAAAAAAAA, 0x55555555};
void fill_pattern(uint32_t *buf, size_t words, uint32_t pattern) { #define bool unsigned char
for (size_t i = 0; i < words; i++) {
buf[i] = pattern; struct tred_pizdec{
uint32_t* mem;
size_t words_stop;
int id;
size_t words_start;
int return_error;
};
#include "multi_tred.h"
// Получить доступную память из /proc/meminfo
unsigned long int get_mem_available_mb() {
FILE* f = fopen("/proc/meminfo", "r");
if (!f) return 0;
char line[256];
unsigned long int available = 0;
while (fgets(line, sizeof(line), f)) {
if (sscanf(line, "MemAvailable: %lu kB", &available) == 1) break;
} }
fclose(f);
printf("mem Gb: %lu\n",(available-1024*500)/1024/1024);
printf("mem MB: %lu\n",(available-1024*500)/1024);
return (available - available/100*10)*1024;
} }
void fill_increment(uint32_t *buf, size_t words) { int parse_t_flag(int argc, char *argv[]) {
for (size_t i = 0; i < words; i++) { for (int i = 1; i < argc; ++i) {
buf[i] = (uint32_t)i; // Вариант -t4
} if (strncmp(argv[i], "-t", 2) == 0) {
} // Если есть еще что-то после -t, например -t4
if (strlen(argv[i]) > 2) {
int check_pattern(uint32_t *buf, size_t words, uint32_t pattern) { char *num_str = argv[i] + 2;
int errors = 0; if (isdigit(num_str[0])) {
for (size_t i = 0; i < words; i++) { return atoi(num_str);
if (buf[i] != pattern) { }
printf("Ошибка в тесте %zu: должен быть: 0x%08X, фактический: 0x%08X\n", i, pattern, buf[i]); }
errors++; // Вариант -t 4
if (errors > 10) break; else if (i + 1 < argc && isdigit(argv[i + 1][0])) {
return atoi(argv[i + 1]);
}
} }
} }
return errors; return -1; // -1 если флаг не найден
} }
int main() {
int main(int argc, char *argv[]) {
if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) { if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
perror("mlockall ошибка!\nВозможно недостаточно прав!\n"); perror("mlockall ошибка!\nВозможно недостаточно прав!\n");
return 1; return 1;
} }
size_t words = BLOCK_SIZE / sizeof(uint32_t); unsigned long int mem_size = get_mem_available_mb();
uint32_t *mem = malloc(BLOCK_SIZE); size_t words = mem_size / sizeof(uint32_t);
uint32_t *mem = malloc(mem_size);
if (!mem) { if (!mem) {
perror("Память выделена!"); perror("Память выделена!");
return 1; return 1;
} }
//struct tred_pizdec* meta[];
// Основные паттерны 0x00000000, 0xFFFFFFFF, 0xAAAAAAAA, 0x55555555 //pthread_t thread[];
for (size_t p = 0; p < sizeof(test_patterns)/sizeof(test_patterns[0]); ++p) { struct tred_pizdec** meta = malloc(sizeof(struct tred_pizdec) * 4);
printf("Запушен патерн 0x%08X\n", test_patterns[p]); pthread_t *thread = malloc(sizeof(pthread_t) * 4);
fill_pattern(mem, words, test_patterns[p]); int tred = parse_t_flag(argc, argv);
printf("Жду\n"); if (tred != -1){
usleep(10000000); // Основные паттерны 0x00000000, 0xFFFFFFFF, 0xAAAAAAAA, 0x55555555
printf("Проверяю\n"); for (size_t p = 0; p < sizeof(test_patterns)/sizeof(test_patterns[0]); ++p){
int err = check_pattern(mem, words, test_patterns[p]); printf("Запушен патерн 0x%08X\n", test_patterns[p]);
if (err == 0) printf("OK\n"); for (bool i = 0;(i != 4); i++){
else printf("Errors: %d\n", err); meta[i] = malloc(sizeof(struct tred_pizdec));
meta[i]->id = p;
meta[i]->mem = mem;
meta[i]->words_stop = words/4*(i+1);
meta[i]->words_start = i * words/4;
DEBUG_PRINT("words_stop: %zu\n",meta[i]->words_stop);
DEBUG_PRINT("words_start:%zu\n",meta[i]->words_start);
pthread_create(&thread[i], NULL, fill_pattern_multi_tred, (void*)meta[i]);
//pthread_join(thread[i], NULL);
}
for (bool i = 0;(i != 4); i++)
pthread_join(thread[i], NULL);
//fill_pattern(mem, words, test_patterns[p]);
printf("Жду\n");
//usleep(10000000);
printf("Проверяю\n");
//int err = check_pattern(mem, words, test_patterns[p]);
for (bool i = 0;(i != 4); i++){
meta[i] = malloc(sizeof(struct tred_pizdec));
meta[i]->id = p;
meta[i]->mem = mem;
meta[i]->words_stop = words/4*(i+1);
meta[i]->words_start = i * words/4;
DEBUG_PRINT("words_stop: %zu\n",meta[i]->words_stop);
DEBUG_PRINT("words_start:%zu\n",meta[i]->words_start);
pthread_create(&thread[i], NULL, fill_increment_multi_tred, (void*)meta[i]);
//pthread_join(thread[i], NULL);
}
int err=0;
for (bool i = 0;(i != 4); i++){
pthread_join(thread[i], NULL);
err += meta[i]->return_error;
free(meta[i]);
}
if (err == 0) printf("OK\n");
else printf("Errors: %d\n", err);
}
}
else{
// Основные паттерны 0x00000000, 0xFFFFFFFF, 0xAAAAAAAA, 0x55555555
for (size_t p = 0; p < sizeof(test_patterns)/sizeof(test_patterns[0]); ++p){
printf("Запушен патерн 0x%08X\n", test_patterns[p]);
fill_pattern(mem, words, test_patterns[p]);
printf("Жду\n");
int err = check_pattern(mem, words, test_patterns[p]);
if (err == 0) printf("OK\n");
else printf("Errors: %d\n", err);
}
} }
// Инкремент // Инкремент
printf("Запушен патерн инкрементации\n"); printf("Запушен патерн инкрементации\n");
fill_increment(mem, words); fill_increment(mem, words);
usleep(10000000); //usleep(10000000);
int err = 0; int err = 0;
for (size_t i = 0; i < words; i++) { for (size_t i = 0; i < words; i++) {
if (mem[i] != (uint32_t)i) { if (mem[i] != (uint32_t)i) {

45
multi_tred.h Normal file
View file

@ -0,0 +1,45 @@
void fill_pattern(uint32_t *buf, size_t words, uint32_t pattern) {
for (size_t i = 0; i < words; i++) {
buf[i] = pattern;
}
}
void fill_increment(uint32_t *buf, size_t words) {
for (size_t i = 0; i < words; i++) {
buf[i] = (uint32_t)i;
}
}
int check_pattern(uint32_t *buf, size_t words, uint32_t pattern) {
int errors = 0;
for (size_t i = 0; i < words; i++) {
if (buf[i] != pattern) {
printf("Ошибка в тесте %zu: должен быть: 0x%08X, фактический: 0x%08X\n", i, pattern, buf[i]);
errors++;
if (errors > 10) break;
}
}
return errors;
}
void* fill_pattern_multi_tred(void *arg) {
struct tred_pizdec* meta = (struct tred_pizdec*) arg;
DEBUG_PRINT("id: 0x%08X\n", test_patterns[meta->id]);
for (size_t i = meta->words_start; i < meta->words_stop; i++) {
meta->mem[i] = test_patterns[meta->id];
}
uint32_t mem_2 = meta->mem[meta->words_start];
DEBUG_PRINT("id_1: 0x%08X\n", meta->mem[meta->words_start]);
DEBUG_PRINT("id_2: 0x%08X\n", mem_2);
return NULL;
}
void* fill_increment_multi_tred(void *arg) {
struct tred_pizdec* meta = (struct tred_pizdec*) arg;
meta->return_error = 0;
for (size_t i = meta->words_start; i < meta->words_stop; i++){
if (meta->mem[i] != test_patterns[meta->id]) {
printf("Ошибка в тесте %zu: должен быть: 0x%08X, фактический: 0x%08X\n", i, test_patterns[meta->id], meta->mem[i]);
meta->return_error++;
if (meta->return_error > 10) break;
}
}
return NULL;
}