Dường như mã này mất khoảng 50 đồng hồ mỗi hoán đổi chút về i7 XPS của tôi 8500 máy. 7,6 giây cho một triệu mảng lật. Đơn luồng. Nó in một số nghệ thuật ASCI dựa trên các mẫu 1 và 0. Tôi xoay pic trái 180 độ sau khi đảo ngược mảng bit, sử dụng một trình soạn thảo đồ họa, và họ trông giống hệt với tôi. Một hình ảnh đảo ngược đôi xuất hiện giống như hình gốc.
Đối với điểm cộng, đó là giải pháp hoàn chỉnh. Nó hoán đổi các bit từ mặt sau của một mảng bit tới mặt trước, so với hoạt động trên ints/bytes và sau đó cần trao đổi int/byte trong một mảng.
Ngoài ra, đây là thư viện bit có mục đích chung, vì vậy bạn có thể thấy nó tiện dụng trong tương lai để giải quyết các vấn đề khác, nhiều sự trần tục hơn.
Có nhanh như câu trả lời được chấp nhận không? Tôi nghĩ rằng nó gần, nhưng không có mã làm việc để chuẩn nó không thể nói. Vui lòng cắt và dán chương trình làm việc này.
// Reverse BitsInBuff.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include "time.h"
#include "memory.h"
//
// Manifest constants
#define uchar unsigned char
#define BUFF_BYTES 510 //400 supports a display of 80x40 bits
#define DW 80 // Display Width
// ----------------------------------------------------------------------------
uchar mask_set[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
uchar mask_clr[] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f };
//
// Function Prototypes
static void PrintIntBits(long x, int bits);
void BitSet(uchar * BitArray, unsigned long BitNumber);
void BitClr(uchar * BitArray, unsigned long BitNumber);
void BitTog(uchar * BitArray, unsigned long BitNumber);
uchar BitGet(uchar * BitArray, unsigned long BitNumber);
void BitPut(uchar * BitArray, unsigned long BitNumber, uchar value);
//
uchar *ReverseBitsInArray(uchar *Buff, int BitKnt);
static void PrintIntBits(long x, int bits);
// -----------------------------------------------------------------------------
// Reverse the bit ordering in an array
uchar *ReverseBitsInArray(uchar *Buff, int BitKnt) {
unsigned long front=0, back = BitKnt-1;
uchar temp;
while(front<back) {
temp = BitGet(Buff, front); // copy front bit to temp before overwriting
BitPut(Buff, front, BitGet(Buff, back)); // copy back bit to front bit
BitPut(Buff, back, temp); // copy saved value of front in temp to back of bit arra)
front++;
back--;
}
return Buff;
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[]) {
int i, j, k, LoopKnt = 1000001;
time_t start;
uchar Buff[BUFF_BYTES];
memset(Buff, 0, sizeof(Buff));
// make an ASCII art picture
for(i=0, k=0; i<(sizeof(Buff)*8)/DW; i++) {
for(j=0; j<DW/2; j++) {
BitSet(Buff, (i*DW)+j+k);
}
k++;
}
// print ASCII art picture
for(i=0; i<sizeof(Buff); i++) {
if(!(i % 10)) printf("\n"); // print bits in blocks of 80
PrintIntBits(Buff[i], 8);
}
i=LoopKnt;
start = clock();
while(i--) {
ReverseBitsInArray((uchar *)Buff, BUFF_BYTES * 8);
}
// print ASCII art pic flipped upside-down and rotated left
printf("\nMilliseconds elapsed = %d", clock() - start);
for(i=0; i<sizeof(Buff); i++) {
if(!(i % 10)) printf("\n"); // print bits in blocks of 80
PrintIntBits(Buff[i], 8);
}
printf("\n\nBenchmark time for %d loops\n", LoopKnt);
getchar();
return 0;
}
// -----------------------------------------------------------------------------
// Scaffolding...
static void PrintIntBits(long x, int bits) {
unsigned long long z=1;
int i=0;
z = z << (bits-1);
for (; z > 0; z >>= 1) {
printf("%s", ((x & z) == z) ? "#" : ".");
}
}
// These routines do bit manipulations on a bit array of unsigned chars
// ---------------------------------------------------------------------------
void BitSet(uchar *buff, unsigned long BitNumber) {
buff[BitNumber >> 3] |= mask_set[BitNumber & 7];
}
// ----------------------------------------------------------------------------
void BitClr(uchar *buff, unsigned long BitNumber) {
buff[BitNumber >> 3] &= mask_clr[BitNumber & 7];
}
// ----------------------------------------------------------------------------
void BitTog(uchar *buff, unsigned long BitNumber) {
buff[BitNumber >> 3] ^= mask_set[BitNumber & 7];
}
// ----------------------------------------------------------------------------
uchar BitGet(uchar *buff, unsigned long BitNumber) {
return (uchar) ((buff[BitNumber >> 3] >> (BitNumber & 7)) & 1);
}
// ----------------------------------------------------------------------------
void BitPut(uchar *buff, unsigned long BitNumber, uchar value) {
if(value) { // if the bit at buff[BitNumber] is true.
BitSet(buff, BitNumber);
} else {
BitClr(buff, BitNumber);
}
}
Dưới đây là danh sách mã để tối ưu hóa bằng bộ đệm mới thay vì hoán đổi byte tại chỗ. Cho rằng chỉ 2030: 4080 BitSet() là cần thiết vì thử nghiệm if(), và khoảng một nửa GetBit() và PutBits() được loại bỏ bằng cách loại bỏ TEMP, tôi nghi ngờ thời gian truy cập bộ nhớ là một chi phí cố định lớn các loại hoạt động này, cung cấp một giới hạn khó để tối ưu hóa.
Sử dụng một cách tiếp cận nhìn lên, và có điều kiện trao đổi byte, chứ không phải là bit, giảm bởi một yếu tố của 8 số lượng bộ nhớ truy cập, và thử nghiệm cho một byte 0 được phân bổ dần qua 8 bit, chứ không phải 1.
Sử dụng hai phương pháp này cùng với nhau, kiểm tra xem toàn bộ 8 bit bit là 0 trước khi thực hiện ANYTHING, bao gồm tra cứu bảng và ghi, có khả năng là cách tiếp cận nhanh nhất có thể, nhưng sẽ yêu cầu thêm 512 byte cho mảng bit đích mới và 256 byte cho bảng tra cứu. Tuy nhiên, hiệu suất hoạt động có thể khá ấn tượng.
// -----------------------------------------------------------------------------
// Reverse the bit ordering in new array
uchar *ReverseBitsInNewArray(uchar *Dst, const uchar *Src, const int BitKnt) {
int front=0, back = BitKnt-1;
memset(Dst, 0, BitKnt/BitsInByte);
while(front < back) {
if(BitGet(Src, back--)) { // memset() has already set all bits in Dst to 0,
BitSet(Dst, front); // so only reset if Src bit is 1
}
front++;
}
return Dst;
Tôi thấy rằng các trang web hiển thị LCD thường có thói quen tốt để ghi dữ liệu vào mô-đun của họ (và theo cả hai hướng). Ngoài ra, vì đây là một vấn đề phổ biến, bảng sở thích (và chuyên nghiệp) cho bộ xử lý của bạn cũng có thể có các thuật toán để thực hiện việc này. – KevinDTimm
Một điều, bạn có thể sắp xếp lại các bit bên trong một byte bằng cách sử dụng bảng tra cứu, ví dụ: '00101101 -> 10110100'. Phần còn lại của vấn đề sau đó sẽ được giảm xuống để nhanh chóng đảo ngược bộ đệm ở mức byte. – stakx
Bạn nên thực sự thực hiện việc này khi đang gửi dữ liệu đến màn hình LCD chứ không phải là một thông báo trước riêng biệt. Xem [câu trả lời của tôi] (http://stackoverflow.com/a/16535315/414813) bên dưới ... – CAFxX